ursus contionabundo: Messung: substr() vers. DateTime

Beitrag lesen

Testskript:

<?php

$dates=[];
for ( $j=1; $j < 100; $j++ ) {
	for ( $m=1; $m < 13; $m++ ) {
		for ( $d=1; $d < 31; $d++ ) {
			#$dates[] = sprintf("%04d-%02d-%02d", $j+2000, $m, $d);
			$dates[] = sprintf("%04d%02d%02d", 2000+$j, $m, $d);
	  }
	}
}
$start=microtime( true );

foreach ( $dates as $date ) {
	$dummy = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-' . substr( $date, 6, 2 );
}
$end=microtime( true );

echo "Methode: substr:\n================\n";
echo ( $end - $start ) * 1000 . " Millisekunden. (Für ". count( $dates )." Werte)\n";
echo ( $end - $start ) / count( $dates ) * 1000000 . " Microsekunden pro Wert\n\n";

$start=microtime( true );

foreach ( $dates as $date ) {
	$dummy = DateTime::createFromFormat( 'Ymd', $date ) -> format('Y-m-d');
}
$end=microtime( true );

echo "Methode: DateTime::createFromFormat:\n====================================\n";
echo ( $end - $start ) * 1000 . " Millisekunden. (Für ". count( $dates )." Werte)\n";
echo ( $end - $start ) / count( $dates ) * 1000000 . " Microsekunden pro Wert\n";

Ergebnis auf amd64 (PHP 7.2.10-0ubuntu0.18.04.1):

Methode: substr:
================
70.26195526123 Millisekunden. (Für 35640 Werte)
1.9714353328067 Microsekunden pro Wert

Methode: DateTime::createFromFormat:
====================================
392.22884178162 Millisekunden. (Für 35640 Werte)
11.005298590954 Microsekunden pro Wert

Ergebnis auf einem armhf (Banana Pi),PHP 7.0.30-0+deb9u1:

Methode: substr:
================
105.8349609375 Mllisekunden. (Für 35640 Werte)
2.9695555818603 Microsekunden pro Wert

Methode: DateTime::createFromFormat:
====================================
2328.6981582642 Millisekunden. (Für 35640 Werte)
65.33945449675 Microsekunden pro Wert

Die Angabe von 14 signifikanten Stellen für die gezeigten Milli- bzw. Microsekunden ist natürlich "sportlich bis nicht ernst zu nehmen", weil diese Genauigkeit auch mit den maximalen 4 Gigaherz des Prozessors (die selbst nicht einmal erreicht werden) nicht erreicht werden kann. Dennoch ist das folgende Fazit zu ziehen:

Wie von mir mit den Worten "Ich gehe einfach davon aus, dass die primitivsten Operationen, die sich um "nichts" (hier die Gültigkeit von Daten) kümmern, auch die schnellsten sind." vorhergesagt ist die primitive Operation mit substr() ca. 5-6 (AMD64) bzw. ~30 (armhf) mal schneller als die immerhin fest kompilierten Methoden der DateTime-Klasse. Die können zwar mehr - aber wenn dieses "mehr" nicht gebraucht wird sollte man bei der Verarbeitung von Massendaten (Pit: "Da es sich um viele Datensätze handelt") diese teuren Funktionen auch meiden.