Technology

Adrian Kirchner
Erschienen am 21. September, 2009
Kommentare
9
Kurz: Ternär-Operator im Benchmark

Kurz: Ternär-Operator im Benchmark

Kaum eine Programmiersprache hat ihn nicht: Den Ternär-Operator (engl.: ternary operator).
Manche Entwickler meiden ihn da er die Lesbarkeit erschweren soll. Andere setzen ihn ein um die Übersichtlichkeit von Methoden zu erhöhen (mich eingeschlossen). Hier wird jedoch nicht der Einsatz diskutiert, sondern die Geschwindigkeit des Operator gegenüber der herkömmlichen If-Abfrage gemessen. Die Benchmarks beschränken sich dabei auf PHP, Java und Perl.

Die Benchmarks sind ziemlich trivial:

  • Zunächst werden die Variablen initialisiert. Dabei handelt es sich in allen Sprachen um zwei Variablen vom Typ String sowie eine Variable vom Typ Integer
  • In einer For-Schleife, die 90.000.000 Mal durchläuft, werden die beiden Strings jeweils per If-Abfrage und per Ternär-Operator verglichen. Ist der Vergleich wahr, wird die Integer-Variable um 1 inkrementiert, sonst um 1 dekrementiert.


Testszenario



PHP

Version
PHP 5.3.0-0.dotdeb.8 with Suhosin-Patch 0.9.7 (cli
(
builtAug 12 2009 18:11:27)
Copyright (c1997-2009 The PHP Group
Zend Engine v2.3.0
Copyright (c1998-2009 Zend Technologies 

Benchmark If / Else
  1. <?php
  2.  
  3. $sValue1 = 'foo';
  4. $sValue2 = 'bar';
  5. $iValueSum = 0;
  6.  
  7.  
  8. for($i = 0; $i < 90000000; $i++) {
  9.  
  10. if($sValue1 === $sValue2) {
  11. $iValueSum += 1;
  12. }
  13. else {
  14. $iValueSum += -1;
  15. }
  16.  
  17. }
Benchmark Ternär
  1. <?php
  2.  
  3. $sValue1 = 'foo';
  4. $sValue2 = 'bar';
  5. $iValueSum = 0;
  6.  
  7.  
  8. for($i = 0; $i < 90000000; $i++) {
  9.  
  10. $iValueSum += ($sValue1 === $sValue2) ? 1 : -1 ;
  11.  
  12. }


Java

Version
java version "1.6.0_12"
Java(TMSE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TMClient VM (build 11.2-b01mixed modesharing

Benchmark If / Else
  1. public class BenchReg {
  2.  
  3. protected static String value1 = "foo";
  4.  
  5. protected static String value2 = "bar";
  6.  
  7. protected static int valueSum = 0;
  8.  
  9. public static void main(String[] args) {
  10.  
  11. for(int i = 0; i < 90000000; i++) {
  12.  
  13. if(value1 == value2) {
  14. valueSum += 1;
  15. }
  16. else {
  17. valueSum += -1;
  18. }
  19.  
  20. }
  21.  
  22. }
  23.  
  24. }
Benchmark Ternär
  1. public class BenchTrin{
  2.  
  3. protected static String value1 = "foo";
  4.  
  5. protected static String value2 = "bar";
  6.  
  7. protected static int valueSum = 0;
  8.  
  9. public static void main(String[] args) {
  10.  
  11. for(int i = 0; i < 90000000; i++) {
  12.  
  13. valueSum += (value1 == value2) ? 1 : -1;
  14.  
  15. }
  16.  
  17. }
  18.  
  19. }


Perl

Version
This is perlv5.10.0 built for i486-linux-gnu-thread-multi 

Benchmark If / Else
  1. my $sValue1 = 'foo';
  2. my $sValue2 = 'bar';
  3. my $iValueSum = 0;
  4.  
  5. for(my $i = 0; $i < 90000000; $i++) {
  6.  
  7. if($sValue1 == $sValue2) {
  8. $iValueSum += 1;
  9. }
  10. else {
  11. $iValueSum += -1;
  12. }
  13.  
  14. }
Benchmark Ternär
  1. my $sValue1 = 'foo';
  2. my $sValue2 = 'bar';
  3. my $iValueSum = 0;
  4.  
  5. for(my $i = 0; $i < 90000000; $i++) {
  6.  
  7. $iValueSum += ($sValue1 == $sValue2) ? 1 : -1;
  8.  
  9. }

Ausführung

Alle Benchmarks wurden auf der Kommandozeile unter Debian GNU/Linux Lenny ausgeführt. Die Zeiten wurden mit dem Kommandozeilen Tool time gemessen.

time php benchmark[1/2].php

time java benchmark[1/2]

time perl benchmark[1/2].pl 


Ergebnis

Wirklich überrascht hat mich nur das Ergebnis der Java-Benchmarks. Die PHP- und Perl-Benchmarks zeigten nur vernachlässigbare Performance-Unterschiede: Diagramm


Tags: - - - - - -
Adrian Kirchner

der autor

Adrian Kirchner

wissensdurstig unterwegs auch im hintersten Ende aller Systeme, spricht fließend PHP, oft nur für Sie.

9 Kommentare

Tobias Müller

Jetzt wäre noch interessant, ob die if-Abfrage noch an Performance gewinnen könnte, wenn im else-Zweig statt

$iValueSum += -1;

Folgendes notiert wäre:

$iValueSum -= 1;

oder

$iValueSum—;

Das dürfte ja eigentlich keine weiteren Performance-Zuwächse bringen, aber man weiss ja nie. wink

Nichtsdestotrotz entkräftet dieses Benchmark auf jeden Fall die Low-Performance-Agumente der Ternär-Gegner. grin

Christopher Orth

Absolut!

Adrian Kirchner

Genau aus diesem Grund hab ich bei allen Benchmarks exakt das gleiche Verfahren verwendet um dort keine Abweichungen einzubauen.

Nils

Netter Beitrag, aber ihr wollt mir doch nicht wirklich weismachen, dass die Schreibweise des ternären Operators wirklich die Lesbarkeit erhöht. Also ich müsste da erst mal ‘ne Weile drauf schauen. Kann aber auch daran liegen, dass ich ? nicht benutze.

Nils

Was mir gerade noch einfällt smile Könnte es nicht sein, dass der Unterschied bei PHP auf 0% sinkt, wenn man einen Bytecode Cache verwendet? Ich tippe mal drauf, dass im Bytecode beide Anweisungen sehr sehr ähnlich aussuchen.
Das würde ja auch dagegen sprechen, dass der ternär Operator langsam wäre.

Adrian Kirchner

Hi Nils,

public function beispiel() {
  return (condition) ? true : false;
}

ich finde das ist wesentlich lesbarer als:

public function beispiel() {
  if(condition) {
      return true;
  }
  else {
      return false;
  }
}


LG

Adrian

Adrian Kirchner

Nachtrag: Zumindest steigt die Übersichtlichkeit einer Klasse

Nils

Mir ging es eher um:

$iValueSum += ($sValue1 === $sValue2) ? 1 : -1 ;

Aber das passt schon smile Habe mich damit abgefunden, dass es einfach Geschmackssache ist.

Adrian Kirchner

Bei dem Beispiel hast du natürlich recht - es ist nicht lesbarer.

Hinterlasse einen Kommentar

Kommentare zu diesem Artikel abonnieren (jederzeit kündbar)