Benchmarks van mijn framework (1)

Door AtleX op maandag 31 december 2007 20:16 - Reacties (5)
Categorie: Development & code, Views: 4.132

Na nog wat uurtjes besteed te hebben aan mijn framework vond ik het wel tijd om eens met wat benchmarks te komen. Ik beloof immers flitsende prestaties, en dat moet ik wel kunnen onderbouwen. :+

Omdat ik de laatste tijd veel werk aan mijn image manipulatie classes heb besteed besloot ik om een kleine variatie op mijn avatar te maken. Namelijk een afbeelding van 60x60 pixels, met een random achtergrond kleur en de tekst van de datum en tijd ook in willekeurige kleuren.

Normaal gesproken zou dat, zonder mijn framework, op de volgende code uitkomen.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
error_reporting(E_ALL);

$plaatje = ImageCreate(60, 60);

imageColorAllocate($plaatje, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));

imagestring($plaatje, 2, 7, 15, date('d-m-y'), imageColorAllocate($plaatje, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)));

imagestring($plaatje, 5, 8, 26, date('H:i'), imageColorAllocate($plaatje, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)));

header("Content-type: image/png");
imagePng($plaatje);
imageDestroy($plaatje);
?>


Bij gebruik van mijn framework heb ik daar de volgende code voor nodig (met wat commentaar):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
error_reporting(E_ALL); // Spreekt voor zich. :+ Iedereen die zonder E_ALL devved moet terug naar school

include("colonna-dev/colonna.php");

$colonna = new Colonna(); // Nieuwe instantie van het framework aanmaken
$colonna->Namespaces->Import("atlex_nl_image"); // Mijn namespace voor image manipulatie includen

$image = new Image(); // Een nieuw image object aanmaken...

$image->Create(60,60,"png"); // ...en daarvan een nieuwe PNG van 60x60 pixels fabrieken. Ik had ook een bestaande image kunnen laden dmv Load()

$painter = new Painter($image); // Painter dient voor het manipuleren van images

$painter->Fill(Color::Random()); // De achtergrond vullen met een random kleur
$painter->DrawString(date('d-m-y'), 2, 7, 15, Color::Random()); // De huidige datum erop schrijven met een random kleur
$painter->DrawString(date('H:i'), 5, 8, 26, Color::Random()); // De huidige tijd erop schrijven met een random kleur

header("Content-type: ".$image->MimeType); // Header geneuzel
$image->GetImageAsBinary(); // En de afbeelding zelf naar de client sturen
?>


Lijkt me prima te begrijpen, toch? Uit beide scriptjes komt hetzelfde resultaat, bijvoorbeeld:
http://tweakers.net/ext/f/klJVWKR8UWoJmRYWhs4diLMk/full.png

Qua benchmarks ben ik een beetje gehandicapt dit keer. Ik heb alleen mijn laptop met een nogal brakke Ubuntu 7.10 installatie tot mijn beschikking. Daar heb ik door middel van Apt Apache 2.2.4 en PHP 5.2.3 op geïnstalleerd. Ook draait de client op de laptop waardoor de testomgeving op z'n zachts gezegd sub-optimaal is. Het benchen is gebeurd door middel van ApacheBench, met de het volgende commando:
akamsteeg@klapjap:~$ ab -c 5 -n 1000 http://localhost/akamsteeg/colonna/icon.php

Hiermee wordt ApacheBench uitgevoerd met 5 gelijktijdige requests, en een totaal van 1000 requests.

In het bestand icon.php staat de code die gebruik maakt van mijn framework, en icon2.php bevat de klassieke benadering. De test is 3x per bestand uitgevoerd, door in een simpel shellscriptje 3 maal het bovenstaande commando op te nemen. De resultaten zijn het gemiddelde uit deze 3 metingen.

Icon.phpIcon2.php
7.605 ms3.926


Is icon2.php sneller? Ja, zonder twijfel. In dit geval zelfs bijna 2x zo snel. Maar volgens mijn bescheiden mening is een performance hit nooit te voorkomen, als je meer functionaliteit toevoegt. Zo wordt binnen die 7.7 ms mijn framework geladen en gestart waarbij onder andere de aleerder beschreven namespace cache opgebouwd word die in dit geval uit 7 namespaces bestaat. Ook wordt de atlex_nl_image namespace geladen, wat weer meer disk I/O geeft.

Om de invloed van de harde schijf te meten heb ik 1 regel code toegevoegd aan icon2.php op regel 3, dus direct onder error_reporting(), die mijn framework include.

PHP:
1
include("colonna-dev/colonna.php");


Let wel, dit include alleen mijn framework maar maakt er nog geen instantie van aan.!

De resultaten zijn dan ineens heel anders, de gemiddelde tijd over 3 runs van 1000 requests per stuk komt dan uit op 6.328 miliseconden. Het verschil is dan ineens nog maar 1.277 ms. tegenover 3.679 ms. zonder dat ene include() regeltje. Voegt mijn framework dus wat overhead toe? Ja, daarover valt niet te discussiëren. Is het minimaal en weegt het dus niet op tegen de voordelen? Ja, wat mij betreft wel.

Voor de oplettende lezer is nu ook meteen de naam van mijn framework bekend, voor de minder oplettende bezoeker: Colonna. Colonna betekent pilaar of zuil in het Italiaans, wat ik wel een mooie naam vond voor iets dat als steunpilaar onder een applicatie staat. :)

Volgende: Gelukkig nieuwjaar 01-'08 Gelukkig nieuwjaar
Volgende: Type hinting in PHP 12-'07 Type hinting in PHP

Reacties


Door Tweakers user XWB, maandag 31 december 2007 21:04

En dan nu de hoofdvraag: maak je dit framework opensource? :)

Door Tweakers user MikeN, maandag 31 december 2007 23:46

Zo, handig zo'n framework.... 6 extra regels code, 2x zo traag, code die niet iedere PHP'er snapt.... Kun je geen representatieve demo maken of is je framework echt alleen een uit de hand gelopen wrapper om PHP heen? ;)

Door Tweakers user AtleX, dinsdag 1 januari 2008 00:19

@Hacku: dat is wel de bedoeling, uiteindelijk. :) Een roadmap of zelfs een bij benadering te noemen datum voor de eerste release is er niet.

@MikeN: tof dat je ook even leest waarom mijn framework trager is. :z Volgens mij ben je na de eerste resultaten al gestopt met lezen om je flame neer te zetten. En nee, het is geen wrapper. Het voegt daadwerkelijk functionaliteit toe, en maakt het programmeren van een aantal zaken behoorlijk makkelijker.

Mijn idee met deze kleine benchmarks is elke keer een klein gedeelte van mijn framework testen, en meteen kleine blikken op de geboden functionaliteit bieden. Is dat representatief? Weet ik niet. Is het als uitgebreide demo bedoeld? Nee, zeker niet.

Als ik deze week nog tijd heb zal ik proberen om met een aantal bestaande open-source PHP frameworks een pagina in elkaar te draaien die overal hetzelfde moet doen. Die kan ik dan benchen om een kleine vergelijking te maken. Zelf dacht ik aan het namaken van mijn avatar, zoals ik 'm nu op GoT gebruik. Deze bevat namelijk behoorlijk wat SQL voor de stats erachter, een beetje disk I/O voor de caching en het inlezen van de background image en image manipulation. Voor een beetje framework moet dat allemaal geen probleem zijn.

[Reactie gewijzigd op dinsdag 1 januari 2008 09:43]


Door Tweakers user MikeN, dinsdag 1 januari 2008 00:48

Het is geen punt als een framework trager is, de rekentijd is vaak veel minder relevant dan de tijd dat het kost om iets te coden. Dat is ook waar frameworks voornamelijk voor bedoeld zijn: sneller kunnen coden. Als jij dan hier een stuk code neerzet waarbij iedere regel eigenlijk gewoon zo ongeveer hetzelfde doet als een regel PHP, en dus slechts de syntax anders is, blijkt daaruit niet echt het nut van je framework. Het enige verschil zit hem in de namespaces. Dat is leuk, maar volgens mij niet een killer feature waarvoor meteen een heel apart framework nodig zou zijn. Het zou dus leuk zijn als je juist kan laten zien hoe je framework echt verschil kan maken :)

Door Tweakers user AtleX, dinsdag 1 januari 2008 09:22

Het voorbeeld was misschien een beetje slecht, omdat je voor de dingen die ik wilde doen nu eenmaal een bepaald aantal acties nodig hebt. :) Je kan immers geen nieuwe afbeelding maken zonder de afmetingen op te geven, en een stukje tekst erop plaatsen zonder de coördinaten is ook niet echt handig. :+ Misschien moet je deze demo dan ook meer zien als een showcase van Object Orientated Image Manipulation in PHP™. :P

Reageren is niet meer mogelijk