Manu: >100.000 dynamische Variablen = Performance?

Hallo zusammen,

zuerst einmal möchte ich an dieser Stelle sagen, dass ohne das Selfhtml-Forum die vergangenen Wochen ein ziemlich großes Wissensloch im deutschsprachigen Internet geklafft - super das das Forum wieder funktioniert! Vielen Dank an alle Selfhtml-Helfer!

Zu meiner Frage betreffend dynamischer Variablen in Javascript: Ich möchte verschiedene Datensätze (jeweils ca. 50-100 Zeichen lang) in ungefähr 100.000 dynamisch generierten Variablen im Cache temporär zwischenspeichern und dann pro Sekunde ca. 1000-2000 dieser Variablen auslesen/ändern.

Hier der Vorgang ganz grob erklärt:

Einmalig >100.000 Datensätze in den Cache laden (in einer Schleife):
window['data'+uniquenumber]="datenxy";

Und dann unterschiedliche Variablen (>1000/Sekunde) auslesen via ("uniquenumber" ist immer bekannt):
datensatz = window['data'+uniquenumber];

Weiß jemand wie Javascript auf diese Art der Nutzung von Variablen reagiert? Gibt es da eine Regel wie: Je mehr unterschiedliche Variablen im Cache, desto langsamer jede "Abfrage"? Wieviel Variablen sollten höchsten gleichzeitig definiert sein, bevor es zu deutlich merkbaren Performance-Einbrüchen (CPU-Last) kommt?

Der oben beschriebene Prozess würde nur auf einem einzigen Rechner mit 16 GB Ram und einen i5-Quadcore CPU laufen.

Viele Grüße
Manu

  1. مرحبا

    Einmalig >100.000 Datensätze in den Cache laden (in einer Schleife):
    window['data'+uniquenumber]="datenxy";

    Für welchen Einsatzzweck braucht man soviele Variablen auf einen schlag?

    mfg

  2. Hi,

    Ich möchte verschiedene Datensätze (jeweils ca. 50-100 Zeichen lang) in ungefähr 100.000 dynamisch generierten Variablen

    100*100.000 = 10.000.000 ==> 10MB.
    Da würde ich mir zuerst die Frage stellen, ob die Browser so viel Speicher für ein Javascript überhaupt zur Verfügung stellen.

    Klar, ich hab jetzt mit der oberen Grenze Deiner Datensatzlänge gerechnet, nicht mit dem Mittelwert. Dafür hab ich aber den Speicherplatz für die keys und sonstigen internen Speicherverwaltungskrempel nicht noch obendrauf geschlagen ...

    (Muß der Key denn zwingend ein String sein? Reicht da nicht ein Integer aus? Wenn's ein String sein muß: bei 100000 keys ist jedes Zeichen weniger eine deutliche Speichereinsparung)

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
  3. Hi,

    Einmalig >100.000 Datensätze in den Cache laden (in einer Schleife):
    window['data'+uniquenumber]="datenxy";

    unabhängig vom bisher gesagtem: warum direkt im window-Objekt? Das könnte javascript insgesamt deutlich verlangsamen, weil viele lookups über das window-Objekt laufen. Außerdem kleisterst du damit den globalen Namespace voll.

    Mach doch wenigstens ein array da draus:
    window['data'][uniquenumber] = "datenxy";

    Noch besser wäre es, es nicht in den globalen Namespace einzuhängen.

    Bis die Tage,
    Matti

    1. [latex]Mae  govannen![/latex]

      window['data'+uniquenumber]="datenxy";

      Mach doch wenigstens ein array da draus:
      window['data'][uniquenumber] = "datenxy";

      Hier würde ich ein Objekt verwenden, man kann sich dann -wie auch in deinem Beispiel - die Verkettung von 'data' mit der uniquenumber sparen, hat aber den Vorteil, auf andere Bezeichner (also nicht-numerisch) umsteigen zu können, ohne den Code noch mal anzufassen. Außerdem wird length bei einem Array falsch gesetzt, wenn bspw. Index 2, 7 und 24 belegt werden.

      var a=[];a[2]=4;a[7]=43;a[24]=0;alert(a.length); // 25

      daher eher so:

      var data = {};  
      data[uniquenumber] = "datenxyz";  
      
      

      Stur lächeln und winken, Männer!
      Kai

      --
      It all began when I went on a tour, hoping to find some furniture
       Followed a sign saying "Beautiful Chest", led to a lady who showed me her best)
      SelfHTML-Forum-Stylesheet
      1. Außerdem wird length bei einem Array falsch gesetzt, wenn bspw. Index 2, 7 und 24 belegt werden.

        var a=[];a[2]=4;a[7]=43;a[24]=0;alert(a.length); // 25

        Falsch würde ich das nicht nennen, sondern das Verhalten, was ich von einem Array erwarten würde: Da gibt length immer den größten belegten Index (+1) wieder.

        Von einem Hash hingegen würde man es natürlich nicht erwarten, da wäre length gleich 3. (In anderen Programmiersprachen, in JavaScript gibts das erst in ES6 mit Map.)

        Mathias

        1. [latex]Mae  govannen![/latex]

          Außerdem wird length bei einem Array falsch gesetzt, wenn bspw. Index 2, 7 und 24 belegt werden.

          var a=[];a[2]=4;a[7]=43;a[24]=0;alert(a.length); // 25

          Falsch würde ich das nicht nennen, sondern das Verhalten, was ich von einem Array erwarten würde:

          „Falsch“ für diesen Verwendungszweck, weil dieses Verhalten hier eher nicht gewünscht ist.

          Von einem Hash hingegen würde man es natürlich nicht erwarten, da wäre length gleich 3. (In anderen Programmiersprachen, in JavaScript gibts das erst in ES6 mit Map.)

          Schöne Sache. Aber bis *das* mal soweit browserübergreifend unterstützt wird, daß man es _in der Praxis_ bedenkenlos auf Websites nutzen kann, bin ich schon unter der Erde.

          Stur lächeln und winken, Männer!
          Kai

          --
          It all began when I went on a tour, hoping to find some furniture
           Followed a sign saying "Beautiful Chest", led to a lady who showed me her best)
          SelfHTML-Forum-Stylesheet
          1. In anderen Programmiersprachen, in JavaScript gibts das erst in ES6 mit Map.

            Schöne Sache. Aber bis *das* mal soweit browserübergreifend unterstützt wird, daß man es _in der Praxis_ bedenkenlos auf Websites nutzen kann, bin ich schon unter der Erde.

            Es ist schon jetzt bedenkenlos verwendbar.

            Mathias

      2. var data = {};

        data[uniquenumber] = "datenxyz";

          
        Hallo Kai345,  
        so eine Lösung hatte ich auch schon im Kopf aber dann dachte ich daran, wie wohl der Array aussieht, wenn 100.000 Datensätze in dem Array "verstreut" sind. Wenn z.B. 100.000 einzigartige Nummern zwischen  1 und 15653482 verteilt wären (nicht fortlaufend, also mit Lücken). Dann muss er ja zwischen 1 bis 15653482 irgendwelche "Freiräume" (Zeilen?) frei halten. Ich werde das aber trotzdem mal testen.  
          
        Ich werde folgedne Variante:  
          
        var data = {};  
        data[uniquenumber] = "datenxyz";  
          
        gegen diese "antreten" lassen:  
          
        this[uniquenumber]=datenxy; (statt "window")  
          
        und 500.000 Datensätze durchjagen und die ms tracken, um zu sehen, welche Variante performanter arbeitet bzw mehr Daten "verträgt".
        
        1. wenn 100.000 Datensätze in dem Array "verstreut" sind. Wenn z.B. 100.000 einzigartige Nummern zwischen  1 und 15653482 verteilt wären (nicht fortlaufend, also mit Lücken). Dann muss er ja zwischen 1 bis 15653482 irgendwelche "Freiräume" (Zeilen?) frei halten.

          Wie gesagt ist ein Array diesbezüglich nur ein Object. Die Lücken bei  »Sparse Arrays« müssen keinen Speicher belegen. Bei der Zuweisung eines Array-Elements wird einfach die length erhöht, sofern sie noch nicht höher ist, es müssen nicht Lücken »reserviert« werden.

          Mathias

  4. Hallo Manu,

    ich glaube, du wirst auf eigene Tests nicht verzichten können. Deine Quadcore-CPU hilft dir hier nicht, da Javascript im Browser (z.Zt.?) nur einen Kern nutzen kann.

    Müssen es Assoziative Arrays / Objekte sein oder gehen auch Arrays mit numerischem Index? Ich kann mir vorstellen, dass der Zugriff über einen numerischen Index schneller geht, als über einen nicht numerischen Objektnamen.

    Brauchst du wirklich alle 100.000 Elemente gleichzeitig? Sonst könnte ein dynamisches Nachladen oder Erzeugen auf Anforderung den Datenbestand im Browser deutlich kleiner halten, und damit auch die Verarbeitungs- und evtl. die Ladezeit verkürzen.

    Gruß, Jürgen

    1. Ich kann mir vorstellen, dass der Zugriff über einen numerischen Index schneller geht, als über einen nicht numerischen Objektnamen.

      Das würde mich eher wundern, denn JavaScript hat keine echten Arrays. Arrays sind per Spezifikation als Objects (Hashes) implementiert. array[0] ist nichts anderes als array["0"], das ist intern dieselbe Operation. Was nicht heißt, dass Interpreter Arrays nicht optimieren können unter der Annahme, sie haben numerische Indizes, aber den Optimierungen sind starke Grenzen gesetzt.

      Mathias

    2. ich glaube, du wirst auf eigene Tests nicht verzichten können. Deine Quadcore-CPU hilft dir hier nicht, da Javascript im Browser (z.Zt.?) nur einen Kern nutzen kann.

      Das Ganze läuft in nodeJS (basiert auf Googles V8-Javascript-Engine, dedizierter Server) mit einer Art CPU-Cluster-System. Das heißt die Javascript-Prozesse werden auf alle vier Prozessorkerne verteilt.

      Müssen es Assoziative Arrays / Objekte sein oder gehen auch Arrays mit numerischem Index? Ich kann mir vorstellen, dass der Zugriff über einen numerischen Index schneller geht, als über einen nicht numerischen Objektnamen.

      Der Variablenname kann auch nur numerisch sein. Das müsste dann schneller sein!?:

      this[uniquenumber]=datenxy;

      Ich werde das ausprobieren vielen Dank für den Tipp!

      Brauchst du wirklich alle 100.000 Elemente gleichzeitig? Sonst könnte ein dynamisches Nachladen oder Erzeugen auf Anforderung den Datenbestand im Browser deutlich kleiner halten, und damit auch die Verarbeitungs- und evtl. die Ladezeit verkürzen.

      Ja ich brauche die Elemente gleichzeitig. Wahrscheinlich werden es noch um ein vielfaches mehr. Die schlechter Alternative wären 2000-3000 Mysql-Abfragen/Sekunde.

      Grüße
      Manu

      1. Ja ich brauche die Elemente gleichzeitig. Wahrscheinlich werden es noch um ein vielfaches mehr. Die schlechter Alternative wären 2000-3000 Mysql-Abfragen/Sekunde.

        Suchst du vielleicht memached? Es hört sich so an, als würdest du da einen Key-Value-Cache bauen. Dafür ist Node.js eher nicht gedacht und die Performance wird in keinem Verhältnis zu memcached, Redis, MongoDB usw. liegen.

        Mathias

        1. Suchst du vielleicht memached? Es hört sich so an, als würdest du da einen Key-Value-Cache bauen. Dafür ist Node.js eher nicht gedacht und die Performance wird in keinem Verhältnis zu memcached, Redis, MongoDB usw. liegen.

          Hi Mathias,

          mit MongoDB hatte ich mich ein bisschen in der Theroie beschäftigt und mich durch diverse "Performance-Diskussionen" (viele Benchmark-Tests) gelesen. MongoDB war teilweise mit der MYSQL MemoryEngine fast auf gleicher Augenhöhe, was mich etwas verwunderte.

          Ich habe mir eben mal memcached installiert und werde es ausprobieren. Danke für den Tipp!

          Grüße
          Manu