range() vs. array_push()

Gestern habe ich Saschas Artikel “Füllen von array-Werten in Reihenfolge: for vs range” entdeckt, in dem er die Performance der PHP eigenen Funktion range() mit der von array_push() in einer for-Schleife vergleicht.

Die allgemeine Erwartung ist sicher, dass range() schneller ist und umso mehr überraschte zumindest mich sein Ergebnis.

Also habe ich schnell einen kleinen Test dafür geschrieben und dabei eine weitere Überraschung erlebt.

Zunächst mein Test-Script, mit dem ich jede Möglichkeit 1000 Mal probiere, um vergleichbare Zahlen zu bekommen. Neben range() und array_push() habe ich auch noch den Operator [] getestet.

<?php
$numLoops = 1000;

$total = 0;
for ($i = 0; $i < $numLoops; $i++) {
  $start = microtime(true);

  $range = range(1,20); 

  $total += microtime(true) - $start;
}

echo 'Gesamtzeit range() = ' . $total . '<br/>';

$total = 0;
for ($i = 0; $i < $numLoops; $i++) {
  $start = microtime(true);

  $range = array();
  for ($j = 1; $j <= 20; $j++) {
    array_push($range, $j);
  }

  $total += microtime(true) - $start;
}

echo 'Gesamtzeit Schleife/array_push() = ' . $total . '<br/>'; 

$total = 0;
for ($i = 0; $i < $numLoops; $i++) {
  $start = microtime(true);

  $range = array();
  for ($j = 1; $j <= 20; $j++) {
    $range[] = $j;
  }

  $total += (microtime(true) - $start);
}

echo 'Gesamtzeit Schleife/[] = ' . $total . '<br/>';

Ein recht gutes Ergebnis sieht so aus und man kann schon sehr gut die Unterschiede sehen.

Gesamtzeit range()               = 0.0055239200592041
Gesamtzeit Schleife/array_push() = 0.015237808227539
Gesamtzeit Schleife/[]           = 0.0075914859771729

In diesem Test brauchte die Schleife mit array_push() doppelt so lange wie die mit dem  []-Oparator und sogar dreimal länger als range().

Das zeigt, dass man sich doch auf die PHP-eigenen Funktionen verlassen kann und dass Faulheit manchmal auch belohnt wird, wenn man statt array_push() nur [] verwendet.

4 Kommentare

  1. Sehr netter Bench, vorher dachte ich mir hum…

    http://softwareentwickler.blogspot.com/2010/06/fullen-von-array-werten-in-reihenfolge.html

    aber dank deinem kommentar aaaah :)

    Gruß
    Alex

  2. Hey Daniel, hab deinen Einwand mal überprüft und meinen Artikel überarbeitet. Danke für den Hinweis ;) Nobody’s perfect …

  3. Hi,

    dass [] schneller als array_push() ist, wusste ich zwar, fand’ ich aber nicht sehr intuitiv – dafür umso beeindruckender. Besonders weil ich den Operator sehr gerne verwende.
    Allerdings kannst du so range() und array_push() meines Erachtens nicht vergleichen bzw. es sollte klar sein, dass range() schneller als array_push() und eigentlich auch als [] ist, denn range() muss nur ein einziges Mal den Adressbereich des Arrays vergrößern (wenn php nicht bereits Puffer dafür zugelegt hat) und array_push() dagegen zwanzig mal. Das ist enorm mehr Aufwand und in höheren Sprachen sicherlich mit noch größeren Performanceunterschieden bei mehr Schleifendurchläufen zu sehen.

    lG

  4. @Julian: Es ging ja um verschiedene Wege, um ein Array mit Werten zu befüllen. Daher lässt sich das schon vergleichen.

    range() sollte klar vorne liegen, da, wie du schon sagtest, der Speicherbereich nur einmal angelegt werden muss und das auch noch unter C.

    Die anderen beiden müssen durch den Interpretor und sind allein deshalb wahrscheinlich langsamer. Ich hoffe allerdings, dass da etwas mehr Intelligenz verbaut ist und nicht mit jedem Element der Speicherbereich vergrößert werden muss.

Schlagwörter: Adapter, Amazon, Animation, Annotations, Anonyme Klasse, Ant, Apache, API, Array, ArrayAccess, Attachment, AutoLoader, Bedienung, Bedingung, Benchmark, Bildbearbeitung, BOM, Bootstrap, Bot, Byte Order Mark, Callback, CamelCase, Canvas, Captcha, Cheatsheet, CLI, Closure, Cloud, CodeSniffer, Community, Comparator, Contest, Controller, Converter, CouchDB, Countable, Cronjob, CSV, CustomLibrary, Custom_Model, Data Mapper, Datei, Datenbank, Datenstruktur, Datentypen, Dating, Decorator, Dekorierer, Design Patterns, Dump, Duplikat, each, Eclipse, Entwicklung, Entwurfsmuster, Enum, Erweiterung, Eventhandling, Exception-Handling, Extension, Factory, Fehler, Flash, Foreach, Formatierung, Formular, Funktion, Futon, Header, HTML5, HTTP, IDE, If, Implementierung, InnoDB, Interceptor, Interface, isset, Iterator, Java, JavaScript, jQuery, Konfiguration, Konsole, Kontrollstruktur, kopieren, Late Static Binding, Layout, Linux, Listeners, Logging, Löschen, Magento, Magic Methods, Marketing, Methode, Model, MVC, MySQL, NetBeans, Objekt, Observable, Observer, OOP, Operator, Parameter, Partnersuche, Performance, PHP, phpMyAdmin, PHPUnit, Plugin, Proxy, Qualitätssicherung, Query, Reflection, Request, Response, Rest-API, Rockstar, Routing, S3, Samba, Scheifen, Schleife, Schutz, Secure Shell, Selbstreferenz, Shop, Sicherheit, Sicherung, Singleton Pattern, SOAP, Sortierung, Sourcecode, Spam, Speicherproblem, Spickzettel, SPL, SSH, Statement, Stellvertreter, Strategy Pattern, Stream, String, Sun VirtualBox, Support, Switch, Symfony, Symfony2, Symfony Live, Tag, Template, Template Method, Ternär Operator, Testing, Thumbnail, Tool, Tour, Twig, Type-Cast, Umwandlung, Underscore, unset, Vererbung, Verzweigung, Video, Videospiel, Virtualisierung, Visitor Pattern, Vorschaubild, walk, Webserver, Webservice, Weiterleitung, Wrapper, Youtube, Zeitsteuerung, Zend Framework, Zend_Cloud, Zend_CodeGenerator, Zend_Http_Client, Zend_Service, Zugriffsmethode