madcats[welt]

Neue Benchmarks

Dromaeo hat vor kurzem ein neues Testverfahren eingeführt. Statt der benötigten Zeit für die Tests, wird nun gemessen, wie viele Durchläufe durchschnittlich pro Sekunde in einer fest definierten Zeit erreicht werden. Das macht die ganze Sache langwieriger, aber auch genauer und sagt wesentlich mehr über die Leistungsfähigkeit einer Javascript Engine aus.

Statt auf zwei unterschiedlichen Systemen zu messen, habe ich nun unterschiedliche Benchmarks gewählt: Dromaeo Javascript Test (Mozilla.org), SunSpider Javascript Test (Webkit-Team) und V8 Javascript Test (Google).

Testergebnisse

Testsystem: Intel Core 2 Duo E8400, 2 GB RAM, Windows XP SP 3

Ein Bild sagt mehr als 1.000 Worte. Chrome deklassiert alle anderen Browser, nur im hauseigenen V8-Test ist das aktuelle Webkit Nightly Build einen Tick schneller. Wie üblich sind die Entwickler-Versionen ihren aktuellen Final-Kollegen deutlich voraus, und die Javascript-Leistung des Internet Explorers, sofern er sich überhaupt testen lies, ist ein schlechter Scherz.

Ein blamables Ergebnis für Microsoft, das mit dem IE 8 auch nicht großartig besser werden wird. Wenn man sich in Redmond angesichts solcher vernichtenden Benchmarks nicht endlich im Zugzwang sieht, sind sie entweder blind und/oder blöd. Google treibt die Entwicklung mit großen Schritten voran, während nur Webkit bzw. Apple halbwegs mithalten kann. Mozilla.org und Opera müssen sich sehr anstrengen, um wieder Anschluss zu finden.

Und Microsoft? Tja, ich sehe nur zwei Möglichkeiten: den ganzen alten IE-Quellcode öffentlich verbrennen und komplett neu schreiben, oder man setzt in Zukunft auf Webkit/Squirrelfish bzw. Webkit/V8 oder Gecko/Tracemonkey.

Von Eichhörnchen-Fischen, Motoren und Spuraffen

Oder anders gesagt: Benchmarks von Squirrelfish, V8 und Tracemonkey mit Hilfe von dromaeo.com.

Testsystem: Intel Core 2 Duo P8600, 2 GB RAM), MacOS X 10.5.6 (MacBook Pro 15″ 2,4 GHz Late 2008)

Ergebnisse (Mac)

Testystem: Intel Core 2 Duo E8400, 2 GB RAM, Windows XP Service Pack 3

Ergebnisse (PC)

Das Squirrelfish schnell ist, war ja schon bekannt. Aber das es V8 und Tracemonkey dermaßen in den Hintern tritt, hätte ich nicht gedacht. Auf die Antwort von Mozilla und Google dürfen wir alle gespannt sein.

Anmerkung zum Internet Explorer: leider konnte ich weder den IE 6 noch 7 dazu bewegen, überhaupt einen Benchmark durchlaufen zu lassen. Entweder meldete er Javascript-Fehler oder stürzte ab. Aus Tests von anderen Leuten, ist aber bekannt, dass er im Vergleich extrem langsam ist – im Schnitt etwa 10 – 15 Sekunden.

Während bei Safari der Taktenraten- und Cache-Unterschied sich noch halbwegs realistisch in den Ergebissen von OS X und Windows widerspiegelt, zeigt sich bei Firefox, dass Mozilla die Mac-Version noch weiter optimieren sollte.

Update: Nun mit Diagrammen statt Text-Ergebnissen.

Sapphire

Wie schon angekündigt, habe ich mit dem Umstieg auf Netbeans begonnen, Sapphire komplett neu zu schreiben. Der eigentliche Kern ist nahezu fertig und die ersten Module in Arbeit – ging alles wesentlich schneller als erwartet. Daher werde ich Ruby nicht mehr weiter entwickeln und die bestehenden Module umschreiben.

Dinge, wie die Mandanten-Fähigkeit noch in Ruby zu integrieren, obwohl sie im Sapphire-Kern schon implementiert sind, ist sinnlos. Außerdem ermöglicht es die neue Struktur wesentlich schneller und besser, Änderungen am Hauptsystem vorzunehmen. Das Portieren der Ruby-Module sollte relativ schnell und unproblematisch laufen.

Die wichtigsten Unterschied zwischen Ruby und Sapphire:

  1. Sapphire ist durchgängig objektorientiert, soweit es PHP 5 ermöglicht.
  2. Es werden ausschließlich Prepared SQL Statements über MySQLi oder PDO unterstützt.
  3. Die Fehler-Verwaltung läuft komplett über Exceptions (SPL und eigene).
  4. Bessere und nun vollständige Implementierung des MVC-Patterns.
  5. Alle Singleton-Patterns wurden entfernt.
  6. Mandantenfähig von Anfang an.
  7. Abstraktionsebene aller Superglobals.
  8. Alle assoziativen Arrays wurden durch Instanzen der Klasse Data ersetzt.
  9. Kleinere Änderungen an der Datenbank, u.a. für die Mandantenfähigkeit. (Ein Import-Script wie von Version 1 auf 2, ist nicht nötig.)

Insgesamt bin ich mit bisherigen Stand sehr zufrieden. Vieles ist im Vergleich zu Ruby einfacher geworden, ganz besonders der Modul-Manager – bei gleichem Funktionsumfang braucht er nur knapp die Hälfte des Quelltexts. Es ist nun wesentlich einfacher, zu überprüfen, ob ein Modul schon geladen ist und an dessen Funktionen heran zu kommen. Zusammen mit einem zukünftig implementierten Observer-Pattern und der Factory des Kerns, ist das die neue Modul-Schnittstelle.

MacBook Pro Erfahrungsbericht #1

Wie versprochen, hier nun der erste Erfahrungsbericht:

Allgemeines

Zwei Tage sind um und ich bin begeistert. Von den Kinderkrankheiten ist nichts zu merken. Es wurde aber ohnehin mit der neuen Firmware ausgeliefert und das Update auf MacOS X 10.5.6 letzte Woche, dürfte auch dazu beigetragen haben, dass keine Probleme aufgetreten sind

MacOS X macht durch die stärkere Hardware und das größere Display erst richtig Spaß. Leider fehlt noch ein Mini Displayport-Adapter auf HDMI, so dass ich das MacBook an meinen Monitor anschließen kann. Spätestens Mitte Januar sollten aber welche verfügbar sein, da Apple die Schnittstellen-Spezifikation allen Herstellern kostenlos zur Verfügung stellt.

Dann mit dem MacBook-Display auf 1440×900 und 1920×1200 auf dem 24″-Monitor, dürfte mein normaler Windows-Rechner arge Konkurrenz bekommen. Allerdings habe ich via Bootcamp nun auch Vista 64 drauf.

Die Installation lief problemlos und kaum langsamer, als auf dem PC. Die anschließende Update-Orgie dauerte mit Service Pack1 und allem drum und dran gute drei Stunden. An der Hardware sollte es aber kaum gelegen haben, obwohl das MacBook nur eine Platte mit 5.400 RPM hat – evtl. tausche ich sie noch gegen eine 7.200er aus.

Arbeit

Arbeiten mit Netbeans gestaltet sich unter OS X genauso komfortabel wie unter Windows. Dank SVN musste ich nur einen Checkout machen und hatte die kompletten Ruby- und Sapphire-Projekte sofort verfügbar. So kann ich jetzt endlich im Zug an Sapphire weiterarbeiten und kann es zuhause einfach ins SVN stopfen. (Gut, das wäre mit dem PowerBook auch gegangen, aber Netbeans lief darauf kaum arbeitstauglich.)

Allein durch die Touch-Gesten, macht es einfach sehr viel Spaß. Fürs Programmieren braucht man definitiv keine Maus mehr: das meiste läuft eh über die – sehr gute – Tastatur, die dank Hintergrundbeleuchtung in dunklen Umgebungen das Tippen erleichert, und alles andere funktioniert perfekt mit dem Multitouch-Trackpad.

Zum vertikalen und horizontalen Scrollen benutzt man einfach zwei Finger. Zoomen und Drehen von Bildern funktionuert wie beim iPhone/iPod touch. Drei Finger um sich iPhoto oder Preview durch die einzeln geöffneten Dateien zu bewegen. Vier Finger nach unten, um Exposé zu öffen; vier Finger nach oben, um Exposé zu schließen, oder falls es geschlossen ist, alle aktive Programme des Spaces zur Seite zu schieben, um den Schreibtisch freizulegen. Außerdem öffnet sich mit vier Fingern horizontal ein Task-Wechsel-Menü.

Apple hat hier sicher noch lange nicht alle Möglichkeiten ausgeschöpft und es werden mit weitere OS X-Versionen sicher noch mehr Gesten folgen. Dazu erleichtert einem die Glasoberfläche das Navigieren erheblich. Bisher habe ich kein Trackpad benutzt, das den Finger ähnlich gut und präzise gleiten lässt. Ingesamt kann man sagen, dass eine Maus komplett überflüssig geworden ist, so lange man nicht pixelgenau arbeiten muss.

Spielen

Der Mac-Client von World of Warcraft ist toll. iTunes ist voll integriert (Hey Blizzard, das geht auf dem PC sicher auch). WoW läuft sehr flüssig, aber leider ist die Geforce 9600M GT mit den neuen Schatten etwas überfordert – man muss ihr aber zu Gute halten, dass selbst die Radeon HD 4870 dabei ordentlich schuften muss. In den nächsten Tagen werde ich unter Vista noch weitere Spiele testen. Außer Blizzard liefert ja dummerweise niemand OS X-Versionen mit.

Fazit

Normale Notebooks mit dieser Hardware mögen deutlich billiger sein, aber Features wie das Multitouch-Trackpad und so viele andere Dinge – und wenn es nur die zwei ausklappbaren Haken zum Kabelaufrollen am Netzteil sind – machen den Preisunterschied mehr als wett. Diese ganzen Kleinigkeiten erleichtern einem die tägliche Arbeit und auch die Freizeit. Der oft ausgesprochene Satz, dass Apple-User nur auf das Design abfahren, mag schon teilweise stimmen. Trotzdem wissen auch viele dies alles zu schätzen. Man merkt einfach, dass Apple bei vielem weiterdenkt, als der Rest und dafür bin ich auch gerne bereit mehr zu zahlen.

Die PC-Konkurrenz hinkt bei Design, Usability, Innovation und selbst der Musikauswahl für Werbung meilenweit hinterher. Der stetig steigende Markanteil von Macs bzw. MacOS X, zeigt doch, dass viele Windows und seine Macken satt haben.

Ich will hier Windows nicht verdammen. Mit XP bin ich seit sieben Jahren sehr zufrieden, aber man kann vieles besser machen und Apple zeigt wie man das anpacken kann. Immerhin hat Microsoft wohl eingesehen, dass Vista ein gigantischer Schuss in den Ofen war und bügelt hoffentlich mit Windows 7 vieles wieder aus. OS X ist zwar in vielen Belangen überlegen, aber in einigen auch nicht und Konkurrenz hat noch keinem geschadet.

Array-Objekte in PHP

Bekanntlich sind Arrays in PHP keine Objekte, wie es z.B. in C# oder Java der Fall ist. Dennoch ist es mit den Interfaces und vorgefertigten Klassen der Standard PHP Library (SPL) möglich, eine Klasse zu entwerfen, die sich wie ein Array verhält. Das mag überflüssig oder überdimensioniert erscheinen, aber ich halte es für ein gutes Beispiel, welche Dinge die SPL möglich macht:

<?php

class MyArray implements ArrayAccess, Countable, Iterator {

	private $data = array();
	public $length = 0;
	private $position = 0;
	private $keys = array();

	public function __construct() {
		$args = func_get_args();

		if(count($args) > 0) {
			foreach ($args as $key => $value) {
				$this->data[$key] = $value;
				$this->length++;
			}

			$this->keys = array_keys($this->data);
		}
	}

	public function __destruct() {
		unset($this->data);
	}

	public function __set($offset, $value) {
		return null;
	}

	public function __call($method, $args) {
		return null;
	}

	public function offsetExists($offset) {
		return isset($this->data[$offset]);
	}

	public function offsetGet($offset) {
		return $this->data[$offset];
	}

	public function offsetSet($offset, $value) {
		$this->data[$offset] = $value;
		$this->length++;
		$this->keys = array_keys($this->data);
	}

	public function offsetUnset($offset) {
		unset($this->data[$offset]);
		$this->length--;
		$this->keys = array_keys($this->data);
	}

	public function count() {
		return $this->length;
	}

	public function rewind() {
		$this->position = 0;
	}

	public function next() {
		$this->position++;
	}

	public function key() {
		return $this->keys[$this->position];
	}

	public function current() {
		return $this->data[$this->key()];
	}

	public function valid() {
		if($this->position < $this->length) {
			return true;
		}

		return false;
	}
}

?>

Interface ArrayAccess:

  • offsetExists()
  • offsetGet()
  • offsetSet()
  • offsetUnset()

Diese Methoden sorgen dafür, dass man das Objekt wie ein ganz normales PHP-Array benutzen kann, d.h. eine Einträge hinzufügen, ausgeben oder löschen.

Interface Countable:

  • count()

Wie der Name schon sagt, gibt die Methode count() einfach nur die Anzahl der aktuellen Array-Items aus.

Interface Iterator:

  • rewind()
  • next()
  • key()
  • current()
  • valid()

Wer vor PHP 4 schon anbord war, wird diese PHP-Funktionen sicher noch kennen, um assoziative Arrays über eine while()-Schleife zu iterieren. Und nichts anderes machen auch die entsprechenden Methoden. Nur sorgen sie in diesem Fall dafür, dass man das Array-Objekt mit foreach() durchlaufen kann.

Zusätzlich sind die magischen Methoden __set() und __call() leer implementiert, so dass man die Eigenschaft $length nicht überschreiben kann und nicht beabsichtigte Methodenaufrufe verhindert werden. Der Konstruktor ermöglicht außerdem wie bei array() beim Initialisieren Werte in das Array zu schreiben.