Benchmark de mon ORM

Pour les besoins d'un nouveau projet, j'ai crée mon propre ORM, que je voulais à la fois simple et rapide.

Histoire de tester ses performances, j'ai fait un benchmark sur les insertions. Au niveau des insertions, j'ai fait un script qui insérait une ligne dans la base de donnée, 1000 fois. Je pense que 1000 était la limite car la durée moyenne était de 27 secondes :p (j'ai atteint à la fin plusieurs fois le temps limite !).

On peux constater deux choses : Mon script ne se débrouille pas si mal, il est aussi rapide que PDO, et à peine plus lent que mysql_query.

Pour les plus perspicaces, vous remarquerez que, à ma grande surprise au début, mon script, qui utilise PDO, est plus rapide que PDO lui-même !

La raison qui me semble être la plus logique, est que plus il y a d'entrées dans la base, et plus les insertions vont mettre du temps. Comme j'ai procédé dans l'ordre : Mon Orm, PDO, mysql_query, PDO devait mettre à peine plus de temps que mon orm car il avait plus d'entrées. Du coup je pense qu'ils sont quasiment aussi rapide (malgré les couches de tests et autres que je fait dans mon orm !).

Voici les divers scripts utilisés et leur résultats :

Script pour mon ORM :

<?php
$iStart = microtime (true);
require_once ('Model/OF_Model_Manager.php');

OF_Model_Manager::prepare('mysql', 'mysql://user@localhost/mydb');

$oArticle = OF_Model_Manager::load('Article', 'mysql');

$oArticle->author_id = 1;

for ($i = 0; $i < 1000; $i++) {
        $oArticle->title = 'Titre Num '.$i;
        $oArticle->unix_title = 'Titre-num-'.$i;
        $oArticle->content = 'Ceci est un content, blah blah blah, provenant du titre Numéro '.$i;
        $oArticle->save ();
}

$iEnd = microtime (true);
echo ' Duration : '.($iEnd - $iStart).' seconds';
?>

Résultats :

  • Test 1 (effectué en 1er) : 25.564520549774 secondes
  • Test 2 (effectué en 4ieme) : 27.423986339569 secondes
  • Test 3 (effectué en 7ieme) : 27.01374206543 secondes
  • Moyenne : 26.667416318258 secondes

Script pour PDO :

<?php
$iStart = microtime (true);
$oPdo = new PDO ('mysql:dbname=mydb;host=localhost', 'user', '');
$oStmt = $oPdo->prepare ('INSERT INTO article (title, unix_title, content, author_id) VALUES (?, ?, ?, 2);');

for ($i = 0; $i < 1000; $i++) {
        $oStmt->execute (array ('Titre Num '.$i, 'Titre-num-'.$i,
                                        'Ceci est un content, blah blah blah, provenant du titre Numéro '.$i));
}

$iEnd = microtime (true);
echo ' Duration : '.($iEnd - $iStart).' seconds';
?>

Résultats :

  • Test 1 (effectué en 2nd) : 26.84337978363 secondes
  • Test 2 (effectué en 5ieme) : 26.360999345779 secondes
  • Test 3 (effectué en 8ieme) : 28.102639913559 secondes
  • Moyenne : 27.10233968099 secondes

Script pour mysql_query

<?php
$iStart = microtime (true);
mysql_connect ('localhost', 'root', 'root');
mysql_select_db ('mydb');

for ($i = 0; $i < 1000; $i++) {
        mysql_query ('INSERT INTO article (title, unix_title, content, author_id) VALUES
                ("Titre Num '.$i.'", "titre-num-'.$i.'", "Ceci est un content, blah blah blah,
                provenant du titre Numéro '.$i.'", 3);');
}

$iEnd = microtime (true);
echo ' Duration : '.($iEnd - $iStart).' seconds';
?>

Résultats :

  • Test 1 (effectué en 3ieme) : 25.734664344787 secondes
  • Test 2 (effectué en 6ieme) : 26.819134092331 secondes
  • Test 3 (effectué en 9ieme) : 28.656072437763 secondes
  • Moyenne : 26.956662995475 secondes

Voici les détails pour chaque méthodes :

Avec mon ORM :

<?php
// ===> Duration : 24.647644042969 seconds
// ===> Duration : 25.101233005524 seconds
// ===> Duration : 24.544696807861 seconds
// ===> Duration : 26.519629955292 seconds
// ===> Duration : 27.009398937225 seconds
// Moyenne : 25.564520549774

// ===> Duration : 29.338793039322 seconds
// ===> Duration : 27.918220996857 seconds
// ===> Duration : 25.035245895386 seconds
// ===> Duration : 26.049331903458 seconds
// ===> Duration : 28.778339862823 seconds
// Moyenne : 27.423986339569

// ===> Duration : 27.986580848694 seconds
// ===> Duration : 26.877804994583 seconds
// ===> Duration : 28.928414821625 seconds
// ===> Duration : 25.827006816864 seconds
// ===> Duration : 25.448902845383 seconds
// Moyenne : 27.01374206543

// Total : 26.667416318258
?>

Avec PDO :

<?php
// ===> Duration : 27.571727991104 seconds
// ===> Duration : 25.589684009552 seconds
// ===> Duration : 29.129471063614 seconds
// ===> Duration : 24.511731863022 seconds
// ===> Duration : 27.41428399086 seconds
// Moyenne : 26.84337978363

// ===> Duration : 25.683578014374 seconds
// ===> Duration : 26.609483003616 seconds
// ===> Duration : 27.286710977554 seconds
// ===> Duration : 25.888841867447 seconds
// ===> Duration : 26.336382865906 seconds
// Moyenne : 26.360999345779

// ===> Duration : 28.10747385025 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> Duration : 29.006589889526 seconds
// ===> > 30 seconds
// ===> Duration : 27.474160909653 seconds
// ===> > 30 seconds
// ===> Duration : 28.444248914719 seconds
// ===> > 30 seconds
// ===> Duration : 27.480726003647 seconds
// Moyenne : 28.102639913559

// Total : 27.10233968099
?>

Avec mysql_query :

<?php
// ===> Duration : 24.602793931961 seconds
// ===> Duration : 26.378651857376 seconds
// ===> Duration : 24.586973905563 seconds
// ===> > 30 seconds
// ===> Duration : 24.560852050781 seconds
// ===> Duration : 28.544049978256 seconds
// Moyenne : 25.734664344787

// ===> Duration : 26.235277891159 seconds
// ===> Duration : 28.628268003464 seconds
// ===> Duration : 26.52792596817 seconds
// ===> Duration : 26.824320793152 seconds
// ===> > 30 seconds
// ===> Duration : 25.87987780571 seconds
// Moyenne : 26.819134092331

// ===> Duration : 27.442328929901 seconds
// ===> > 30 seconds
// ===> Duration : 28.583750009537 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> Duration : 29.412082910538 seconds
// ===> > 30 seconds
// ===> Duration : 29.186127901077 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds
// ===> > 30 seconds (abandon ...)
// Moyenne : 28.656072437763

// Total : 26.956662995475
?>

Vous remarquerez qu'avec mysql_query, à la fin c'est totalement la folie, je ne pouvais plus insérer 1000 éléments sans dépasser les 30 secondes !

Vous remarquerez aussi que PDO et Mysql ont dépassé, avant le 3ieme test, au moins une fois les 30 secondes, tandis que mon ORM, jamais, même dans la 3ième slave !

Bon, il faut aussi savoir qu'à la fin, j'avais environ 69 000 entrées dans ma base !

Je vais tester les select (avec/sans limit) et les delete, sur tout ça, histoire de voir les performances :p

Tout ceci s'annonce prometteur ! :)

Posted by Cyril Nicodème