FizzBuzz without ifs in 90 characters

16. 7. 2015

V návaznosti na tento post jsem si sem přidal své varianty s tím, že nad nimi budu dumat dál, až bude čas. (...)

PHP: 76

for($i=1;$i<101;$s=['Fizz'][$i%3].['Buzz'][$i%5],print[$i++,$s][!!$s]."\n");

Ruby: 78

(1..100).map{|i|puts (['Fizz'][i%3].to_s+['Buzz'][i%5].to_s).sub(/^$/,i.to_s)}

JavaScript: 79

for(var i=1;i<101;i++){console.log((['Fizz'][i%3]||'')+(['Buzz'][i%5]||'')||i)}

Komentáře (2) Přidat komentář


ErrorPresenter vs persistentní parametry

26. 6. 2015

Aplikace je lokalizovaná a Nette nám persistentní parameter (v basePresenteru) $locale hezky pži každém requestu automaticky naplňuje. To je fajn, máme ho všude k dispozici. Po nějaké době chceme lokalizovat i chybové stránky. Otevřeme si ErrorPresenter, abychom načítali pokaždé jinou šablonu. Ujistíme se, že dědí od BasePresenteru a vesele začneme $this->locale používat. Jak nejrychleji nasimulovat chybu? Zapneme produkční prostředí a odkážeme na neexistující URL. Hele, nefunguje to. Po několikaminutovém hledání a zkoumání si potvrdíme, že do ErrorPresenteru se opravdu persistentní parametry nepředávají (v tomto případě).

Application\Application

Popišme si dvě situace, při kterých může dojít k "vyhození erroru".

  1. Chyba během aplikace - například zavolání neexistující metody $this->hello(); v HomepagePresenteru
  2. Chybná URL (Bad request)

Ad 1, $container->getByType('Nette\Application\Application')->run() - Tento kousek kódu zná každý. V metodě Application::run() se podle Htttp\Request vytvoří Application\Request, který už vede na konkrétní Presenter. Na Presenteru se pak zavolá ::run(). My jsme však v Presenteru způsobili chybu zavoláním neexistující metody...

Ad 2, Application::run() běží stejně, jako v prvním případě. Aplikace chce vytvořit Application\Request, ale už tady selže, bum...

Předchozí situace se rozejdou na řádku Application.php s voláním $this->processRequest($this->createInitialRequest());. Poprvé se stihne úspěšně zavolat Application::createInitialRequest() a teprve při zpracování požadavku aplikace umře. Podruhé Application::processRequest() nevrátí požadovaný request s patřičnými parametry - těsně před vrácením requestu vyhodí BadRequestException. V první situaci se tedy do Presenteru stihnou propsat náležité parametry a v ErrorPresenteru můžeme lokalizovat pomocí persistentní property $locale. A teď bychom rádi dostali parametr i do druhé situace.

Routříčku, otřes se

Application\Request se tvoří na začátku metody Application::createInitialRequest() nehledě na to, zda je cíl požadavku dostupný či ne. Pokud máme připravenou nějakou "fallback routu" pro určení alespoň lokalizace (na základě hostu, apod), můžeme se pokusit získat znovu Application\Request, aniž bychom se ho snažili protlačit k životu. Někde tedy znovu zavoláme Application::router->match(Http\Request); a pokusíme se ve vráceném požadavku najít naše parametry.

Nette\Object

Ať už pomocí Kdyby\Events, nebo jinak si zaregistrujeme událost Application::onError. Událost se v případě chyby spustí a jako argument dostaneme instanci Application a vyhozenou Exception. Událost bude muset odněkud získat Http\Request. Pomocí knihovny Kdyby\Events si ji jednoduše předáme pomocí konstruktoru. Když máme událost připravenou, něco do ní napíšeme:

public function onError(Application $application, Exception $exception)
{
	$application_request = $application->router->match($this->httpRequest);
	$request_parameters = $application_request->getParameters();
	$locale = $request_parameters['locale'];
}

Tím jsme sice získali kýžený parametr, ale v ErrorPresenteru stále není. Nejjednodušší cestu vidím v uložení parametru do session (kterou si předáme konstruktorem) a načtení parametru ze session v ErrorPresenteru. Cest je samozřejmě mnoho. Vyberte si tedy vaši.

Přidat komentář


Zrychlujeme!

29. 4. 2015

Kdo by rád neporovnával benchmarky PHP frameworků... Dnes jsem zavadil o Laravel Lumen. Ideální pro tvorbu API, jak píše autor Taylor Otwell. Zároveň uvádí, že Lumen zvládne kolem "1900 requests per second". Jistě, týká se to out-of-box frameworku, ale i tak je to pozoruhodné, nebo spíš zajímavé číslo. Pojďme si vzít stopky do ruky sami.

Ahoj světe, Nette

Začneme, jak jinak, Nette Sandboxem. Standardní composer create-project nette/sandbox odpovídá na cca 108 requestů/s. Nette Microframework si s odpovědí pospíší - čas requestu je přibližně poloviční. Abychom však porovnávali s Lumenem čísla ve stejném prostředí, musíme stopnout čas i jemu na našem železe. Stejně jako dosud testované frameworky i tento pustíme bez jakýchkoliv APC a jiných cachí. Podívejme, Lumen odpoví po cca 13 ms. Počet requestů za sekundu vyjde na 763. "Velký" Laravel je na tom přitom znatelně hůře než Nette Sandbox - 35 requestů/s s průměrným časem odezvy 284 ms.

Na čem to všechno "jedu"

PHP 5.6, Vagrant 1.7.2, NGINX 1.6.2, Virtualbox 4.3, 2GB RAM. Na Macbooku (mid-2012) běží ještě další servery a nějaká multimédia, klasika

HHVM

Pokud za NGINX ještě zřetězíme HHVM, Sandbox Nette zvládne přibližně 160 requestů/s, průměrný request 63ms, micro verze je víe jak dvojnásobně rychlejší. Lumen se vyhoupne na zhruba 1050 requestů/s s průměrnou dobou 10ms.

Edit: Pro srovnání jsem přidal ještě framework Phalcon. Srovnávat Phalcon s/bez HHVM nemá smysl, ve výsledcích je tedy zahrnut pouze benchmark bez HHVM..

Kompletní výsledky

Bez HHVM:
	Laravel Lumen:
		Requests per second:    762.79
		Time per request:       13.110 [ms]

	Laravel:
		Requests per second:    35.18
		Time per request:       284.238 [ms]

	Nette Sandbox:
		Requests per second:    108.78
		Time per request:       91.929 [ms]

	Nette Micro:
		Requests per second:    219.15
		Time per request:       45.630 [ms]

	Phalcon:
		Requests per second:    1452.03
		Time per request:       6.887 [ms]

HHVM:
	Laravel Lumen:
		Requests per second:    1044.99
		Time per request:       9.569 [ms]

	Laravel
		Requests per second:    57.55
		Time per request:       173.762 [ms]

	Nette Sandbox:
		Requests per second:    158.25
		Time per request:       63.191 [ms]

	Nette Micro:
		Requests per second:    367.35
		Time per request:       27.222 [ms]

Komentáře (8) Přidat komentář

Tento web používá k poskytování služeb a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tím souhlasíte. V pořádku Další informace