Hi!
Als Anwender erwarte ich, dass auf meinen Klick hin etwas passiert und nicht irgendwann später. Die Zeit zwischen zwei Klicks ist ja nicht nur in diesem Fall abhängig davon, wie lange ich mir ein Bild betrachte, sondern es kommt auch noch die hinzu, die zwischen dem Klick und dem Erscheinen des nächsten Bildes vergeht. Und die sollte gegen Null tendieren. Das erwarte ich als Anwender, sonst klicke ich nochmal, weil ich denke, dass es nicht getroffen hat.
Nun übertreib' mal nicht! Die Zeit für ein push(shift()) oder unshift(pop()) ist unabhängig von der Arraylänge absolut nicht spürbar, wenn das vom Benutzer durch Klicken einzeln ausgelöst wird. Allenfalls mit vielen Schleifendurchläufen könnte man sie spüren.
Ok, ich sehe erst ab 1 Million Array-Elementen im FF 3.6.8 eine leichte Verzögerung (und immer noch keine im IE8). Die Performance-Frage ist also für handelsübliche Bildermengen irrelevant.
Es wird hier auch immer angedeutet, dass intern ein Riesenaufwand für's Umschichten der Array-Elemente stattfinden muss. Woher weiß man das?
Ich weiß aufgrund meiner Kenntnisse, dass es mehr Aufwand ist, als lediglich einen Zähler zu inkrementieren.
Ich kann mir vorstellen, das intern sehr optimierter Code läuft. push(shift()) etc. ist jedenfalls recht schnell,
Es gibt einen Unterschied zwischen einfachen Typen wie Zahlen und komplexeren wie Objekten. Die eigentlichen Daten eines Objekts bleiben im Speicher stehen, lediglich Referenzen darauf müssen umsortiert werden. Einfache Typen werden direkt umgeschichtet. Der Aufwand ist in beiden Fällen ziemlich gleich, weil einfache Typen und Referenzen jeweils nur aus wenigen Bytes bestehen. Das Array (mit den einfachen Werten oder den Referenzen) belegt einen bestimmten Speicherbereich. Davor und danach ist nicht genügend Platz. Vermutlich wird ein bisschen mehr Platz reserviert worden sein, damit nicht bei jeden neu anzuhängenden Element das gesamte Array auf einen größeren Platz umkopiert werden muss. Jedenfalls ist nicht so viel Platz vorhanden, dass es in alle Ewigkeit beim Rotieren in die eine oder andere Richtung wandern kann. Interessant sind hierbei nur die Methoden shift() und unshift(). pop() ist unkritisch, push() meistens auch, weil der vermutete Puffer verwendet werden kann, jedenfalls bis er voll ist und ein Umkopieren in einen größeren Bereich oder was adäquates notwendig ist. Was also kann shift() und unshift() machen?
Man kann:
- die Elemente im vorhandenen Platz nachrutschen lassen.
- Elemente können in neuer Formation an neu reservierten Platz umkopiert werden.
Je nachdem, wie beide Vorgänge optimiert sind, verbrauchen sie Zeit. Auf Maschinencode-Ebene würde man einen Speicherbereich verschieben und wäre schnell, weil ein Prozessor sowas ständig machen muss und darauf optimiert ist. Je weiter man sich die Abstraktionsebenen nach oben hangelt, desto weniger kann man mit Speicherbereichen an Variablentypgrenzen vorbei direkt hantieren. Hier kommt es dann auf die jeweilige Implementation an, was wirklich passiert. Ich nehme mal an, dass der FF die Elemente einzeln umlagert, denn irgendwoher muss sein Zeitverbrauch ja herkommen.
Eine verkettete Liste wäre das Gebilde mit dem wenigsten Aufwand beim Umsortieren. Die Elemente stehen irgendwo im Speicher und Vorgänger und Nachfolger (oder auch nur in eine Richtung) sind durch Referenzen bekannt. Man muss nur die Referenen von maximal drei Elementen ändern, um ein Element zu entfernen oder irgendwo einzufügen. Allerdings wird ein Array nicht als vL gespeichert werden, weil mit dieser kein Zugriff auf Position X einfach möglich wäre. Man müsste sich dazu nämlich an der Kette entlanghangeln und mitzählen oder einen zusätzlichen Index aufbauen. Doch dann kommt man vom Regen in die Traufe, weil bei einer Änderung dieser Index umsortiert oder neu aufgebaut werden muss. VL scheiden also aus.
Weitere Möglichkeiten?
Lo!