Beim Vergleich verschiedener Serialize-Algorithmen schneidet der PHP-Serializer am schlechtesten ab
Da es immer wieder Unklarheiten gibt darüber, wie schnell ein Serializer eine Datei zu einer komplizierten Datenstruktur wiederbelebt, habe ich mir mal die Mühe gemacht, dies genauer zu untersuchen. Hier die Datenstruktur:
# EAV: Entity Attribute Value my $data = { env => { foo => 'bar' } };
Im Folgenden die verglichenen Algorithmen. Der Unterschied zwischen einer mit textlichen Mitteln (JSON, PHP-Serialize) serialisierten Sequenz und einer Low-Level-Serialisierung auf Byte-Ebene (Storable, eigene Algorithmen) wird deutlich:
Unter dem Schlüsselwort phpser in untenstehender Tabelle zu finden. Der Algorithmus, in PHP für die Funktionen serialize(), unserialize() zum Einsatz kommend, ist für diesen Test in Perl implementiert.
Von allen anderen Serialize-Algorithmen schneidet dieser am schlechtesten ab.
Als Funktionsname jsons in der Tabelle. Etwas schneller als der in PHP verwendetet Algorithmus.
storab ist das Schlüsselwort für die Ergebnistabelle untenstehend.
altern und atonce bilden ähnliche Algorithmen ab.
Am schlechtesten schneidet der PHP Serializer ab.
Rate phpser jsons storab altern atonce phpser 1749/s -- -55% -74% -79% -82% jsons 3879/s 122% -- -42% -53% -60% storab 6734/s 285% 74% -- -18% -31% altern 8210/s 370% 112% 22% -- -15% atonce 9699/s 455% 150% 44% 18% --
#!/usr/bin/perl use strict; use warnings; use IO::String; use Storable qw(freeze thaw); use Data::Dumper; use Benchmark qw(cmpthese timethese); use PHP::Serialization qw(serialize unserialize); use JSON; # EAV: Entity Attribute Value my $data = { env => { foo => 'bar' } }; # EAV im Wechsel serialisieen my $altern = sub{ my $io = IO::String->new; foreach my $ent( keys %$data){ foreach my $att( keys %{$data->{$ent}} ){ my $val = $data->{$ent}{$att}; $io->print( pack('N', length $ent), $ent, pack('N', length $att), $att, pack('N', length $val), $val ); } } my $res = {}; $io->seek(0,0); while( read($io, my $elen, 4) ){ read($io, my $ent, unpack('N', $elen)); read($io, my $alen, 4); read($io, my $att, unpack('N', $alen)); read($io, my $vlen, 4); read($io, my $val, unpack('N', $vlen)); $res->{$ent}{$att} = $val; } #print Dumper $res; }; # EAV am Stück serialisieren my $atonce = sub{ my $io = IO::String->new; foreach my $ent( keys %$data){ foreach my $att( keys %{$data->{$ent}} ){ my $val = $data->{$ent}{$att}; $io->print( pack('NNN', length $ent, length $att, length $val), $ent, $att, $val ); } } my $res = {}; $io->seek(0,0); while( read($io, my $buffer, 12) ){ my ($elen,$alen,$vlen) = unpack 'NNN', $buffer; read($io, my $ent, $elen); read($io, my $att, $alen); read($io, my $val, $vlen); $res->{$ent}{$att} = $val; } #print Dumper $res; }; my $storab = sub{ my $io = IO::String->new; $io->print(freeze($data)); $io->seek(0,0); my $str = ''; while( read($io, my $buffer, 102) ){ $str .= $buffer } my $res = thaw($str); #print Dumper $res; }; my $phpser = sub{ my $io = IO::String->new; $io->print(serialize($data)); $io->seek(0,0); my $str = ''; while( read($io, my $buffer, 102) ){ $str .= $buffer } my $res = unserialize($str); #print Dumper $res; }; my $jsons = sub{ my $io = IO::String->new; $io->print(encode_json($data)); $io->seek(0,0); my $str = ''; while( read($io, my $buffer, 102) ){ $str .= $buffer } my $res = decode_json($str); #print Dumper $res; }; cmpthese(10000, { 'altern' => $altern, 'atonce' => $atonce, 'storab' => $storab, 'phpser' => $phpser });
Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. sos@rolfrost.de.