PHP Internationalisierung (i18n) Benchmark

Internationalisierung ist heute in größeren Projekten sehr wichtig. Dabei gibt es viele verschiedene Ansätze, die gute oder weniger gute Performance bieten. Grundsätzlich basieren diese aber meist auf String-Arrays oder kompilierte Textdateien. Ich möchte heute etwas Licht ins Dunkel bringen und einige Ansätze einen Benchmark Test unterziehen.

Die Testkandidaten

Ich werde 4 verschiedene Methoden testen:

String-Array

Dabei werden alle Strings einer Sprache in einem Array gespeichert. Desweitern wird für jeden String ein eindeutiger Index gewählt. Mit diesem Index wird dann der passende String ausgewählt.

So etwas könnte in etwa so aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//z.B. lang_de.php
$lang['test2'] = 'Dies ist ein kleiner Test';
 
//Ausgabe
function test1()
{
    global $lang;
 
    echo $lang['test2'];
}
?>
<p><?php echo $lang['test2']; ?></p>

Vorteile:

  • Schnell implementiert

Nachteil:

  • Das String-Array muss gobal verwaltet werden
  • Jeder String muss einen eindeutigen Index haben, was jeden Programmierer bekannt sein muss
  • Hinzufügen neuer Übersetzungen sind mühsam

Language Klasse

Hier werden wie beim String-Array alle Übersetzungen in mehreren Arrays gehalten, die dann über die Language Klasse aufgerufen werden können.

Vorteil:

  • Zentrale Verwaltung
  • Keine globale Variable

Nachteil:

  • Auch hier muss ein eindeutiger Index vorhanden sein
  • Unnütze Funktionsaufrufe

Gettext

Gettext ist eine NLS (Native Language Support) API Implementierung, die dazu verwendet werden kann, um ein PHP-Projekt zu internationalisieren. Dabei gibt es Gettext als PHP-Erweiterung oder als PHP-Implementierung. Ich werde beide testen.

Die Implementierung könnte etwa so aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
putenv('LC_ALL=de_DE');
setlocale(LC_ALL, 'de_DE');
bindtextdomain('de_DE', './locale');
textdomain('de_DE');
 
//Ausgabe
function test1()
{
    echo _("This is a small test");
}
?>
<p><?php echo _("This is a small test"); ?></p>

Dabei werden alle String in einer oder mehreren kompilierten *.mo Dateien verwaltet.

Vorteile:

  • Keine extra Klasse oder globale Variablen nötig
  • Leicht zu verwaltende Spachdateien
  • Leicht zu Implementieren
  • Default Sprache muss nicht übersetzt werden

Nachteile:

  • Gettext-Erweiterung muss auf dem Server installiert sein
  • Gettext-PHP Implementierung Langsam

Testsystem

CPUAMD Phenom II X4 965
RAM8GB DDR3 CL7
MainboardGA-890GPA-UD3
HDDSSD C300
RAID 1 Samsung F3 1TB
EnergieoptionHöchstleistung
BetriebssystemWindows 7 SP1 64Bit
Ubuntu 10.04 32Bit (VM)
SoftwareApache 2.2.17
PHP 5.3.5

Benchmark

  • 15.000 Durchläufe mit den Apache Benchmarktool ab
  • ca. 300 Strings und davon werden ca. 100 ausgegeben (bei allen Tests)
TestUbuntu (RPS)Windows (RPS)
Gettext-Ext1115,40355,03
Gettext-Ext (default)1174,48324,60
Gettext-PHP156,43115,70
Gettext-PHP (default)600,04480,86
String Array701,87593,30
Language Class525,03324,60

weitere Bilder

Zeigen »

 

 

Fazit

Dass die Gettext-PHP Implementierung haushoch verloren hat, war abzusehen. Was ich aber nicht gedacht hätte, ist dass die Gettext-Erweiterung gewonnen hat, gerade weil die String-Array Implementierung wirklich primitiv ist. Desweitern hat mich verwundert, dass es so einen Unterschied zwischen Windows und Linux gibt. Was aber nicht wirklich weiter schlimm ist, da ohnehin im WWW zu 80% Linux Server eingesetzt werden.

Bis jetzt habe ich immer in meinen Projekten eine Language Klasse mit einem String-Array eingesetzten. Aber wenn ich so die Benchmark Ergebnisse ansehe, werde ich bestimmt in meinen nächsten Projekten Gettext verwenden. Ich werde darüber auch noch einen genauen Artikel schreiben, wie man Gettext einsetzt und die Sprachdateien erstellt und verwaltet.

Download

Alle Quellcode-Dateien & Bilder könnt ihr hier runterladen.

 

Ich hoffe euch hat dieser Artikel gefallen. Zu Fragen oder Anregungen stehe ich euch gern zur Verfügung.

Schlagwörter: , , , ,

7 Kommentare bisher »

  1. Oliver sagt

    am 7. August 2011 @ 23:39

    Übrigens WordPress benutzt immer noch die PHP Version von gettext und es ist das schnellste, weil die Ersetzung nicht von PHP vorgenommen wird. Gettext selbst ist hochoptimiert, weil so ziemlich jedes Linuxprogramm das benutzt.

  2. admin sagt

    am 8. August 2011 @ 01:04

    Ja das ist richtig, dass WordPress eine PHP Implementierung von Gettext nutz. Ob dies die schnellste Methode ist bezweifel ich aber. Denn die Funktion load_default_textdomain benötigt z.B. bei mir ca. 919ms (localhost + DE-WP). Ich denke dies kann man besser lösen.

  3. Oliver sagt

    am 8. August 2011 @ 02:30

    Ne, nutzt es nicht – patchen macht es 4 mal schneller.

    http://core.trac.wordpress.org/attachment/ticket/17268/wp_gettext_v3.patch

  4. admin sagt

    am 8. August 2011 @ 10:36

    Ok mit diesem Patch.

    Ich würde es aber nur auf einen Test-Server installieren. Denn dieser Patch hat einige Fehler.

  5. Cheesi sagt

    am 2. Februar 2013 @ 15:11

    Gibt es auch irgendwo ein gutes Tutorial für gettext? Finde irgendwie nichts brauchbares…

  6. admin sagt

    am 8. Februar 2013 @ 16:24

    Hallo Cheesi,

    du wirst es kaum glauben aber ich bin gerade dabei eins zu schreiben, noch etwas Geduld.

  7. Cheesi sagt

    am 16. Februar 2013 @ 20:48

    @admin Cool :) Freu mich schon. Zwischenzeitlich hab ich folgendes gefunden: http://mel.melaxis.com/devblog/2005/08/06/localizing-php-web-sites-using-gettext/

Komentar RSS · TrackBack URI

Hinterlasse einen Kommentar

Name: (erforderlich)

eMail: (erforderlich)

Website:

Kommentar: