Ich habe ein Lua-Programm, das langsamer zu sein scheint, als es sein sollte. Ich vermute, dass das Problem ist, dass ich Werte zu einem assoziativen Array einzeln hinzufüge und die Tabelle jedes Mal neuen Speicher zuweisen muss.
Es schien eine table.setn-Funktion zu geben, aber sie schlägt unter Lua 5.1.3:
fehl %Vor%Ich erfasse aus der Google-Suche, dass diese Funktion in Lua 5.1 abgeschrieben wurde, aber ich kann nicht finden, was (wenn überhaupt) die Funktionalität ersetzt hat.
Wissen Sie, wie man eine Tabelle in Lua vorfasst?
Gibt es alternativ eine andere Möglichkeit, Speicherzuweisung zu vermeiden, wenn Sie ein Objekt zu einer Tabelle hinzufügen?
Lassen Sie mich mehr auf Ihre Frage eingehen:
Hinzufügen von Werten zu einem assoziativen Array eins nach dem anderen
Tabellen in Lua sind assoziativ, aber ihre Verwendung in einer Array-Form (1..N) ist optimiert. Sie haben innen zwei Gesichter.
Also ... Wenn Sie Werte assoziativ hinzufügen, folgen Sie den obigen Regeln.
Wenn Sie Indizes 1..N verwenden, können Sie eine einmalige Größenänderung erzwingen, indem Sie t [100000] = etwas setzen. Dies sollte bis zum Limit der optimierten Array-Größe funktionieren, die in Lua-Quellen angegeben ist (2 ^ 26 = 67108864). Danach ist alles assoziativ.
ps. Die alte 'setn'-Methode behandelte nur den Array-Teil, also ist es für assoziative Verwendung nicht sinnvoll (ignoriere diese Antworten).
pp.s. Haben Sie allgemeine Tipps zur Aufrechterhaltung der Lua-Leistung studiert? d. h. Erstellen einer Tabelle und eher Wiederverwendung einer Tabelle als Erstellen einer neuen, Verwendung von 'local print = print' und so, um globale Zugriffe zu vermeiden.
Ich glaube nicht, dass Sie das können - es ist kein Array, es ist ein assoziatives Array, wie ein Perl-Hash oder ein awk-Array.
Ich denke nicht, dass Sie seine Größe sinnvollerweise von der Lua-Seite aus voreinstellen können.
Wenn Sie jedoch das Array auf der C-Seite zuweisen, ist das
%Vor%kann sein, was Sie brauchen.
Erzeugt eine neue leere Tabelle und schiebt es auf den Stapel. Die neue Tabelle hat Speicherplatz, der für Narr-Array vorbelegt ist Elemente und nrec Nicht-Array-Elemente. Diese Vorbelegung ist nützlich, wenn Sie genau wissen, wie viele Elemente die Tisch wird haben. Ansonsten können Sie verwenden die Funktion lua_newtable.
Dann, in Lua,
%Vor% Als einen schnellen Hack, um das zu erreichen, können Sie das C zu lua.c
hinzufügen.
Wenn Sie Ihre Tabelle im Code mit einer bestimmten Anzahl von Elementen deklarieren, so:
%Vor% Dann erstellt Lua die Tabelle mit dem Speicher, der bereits für mindestens n
items reserviert ist.
Lua verwendet jedoch die 2x inkrementelle Speicherzuweisungstechnik, sodass das Hinzufügen eines Elements zu einer Tabelle selten eine Neuzuweisung erzwingen sollte.
Es gibt immer noch einen internen luaL_setn und du kannst Lua so kompilieren es wird als table.setn verfügbar gemacht. Aber es sieht so aus, als würde es nicht helfen weil der Code scheint keine Vorverlängerung zu tun.
(Auch das setn, wie oben erwähnt, bezieht sich auf den Array-Teil eines Lua-Tisches, und du hast gesagt, dass du den Tisch als assoziativ verwendest Array)
Der gute Teil ist, dass, selbst wenn Sie die Elemente einzeln hinzufügen, Lua nicht Erhöhe das Array auf diese Weise. Stattdessen verwendet es eine vernünftigere Strategie. Du immer noch Erhalten Sie mehrere Zuweisungen für ein größeres Array, aber die Leistung ist besser als Immer eine neue Zuweisung bekommen.
Obwohl dies Ihre Hauptfrage nicht beantwortet, beantwortet es Ihre zweite Frage:
Gibt es alternativ eine andere Möglichkeit, Speicherzuweisung zu vermeiden, wenn Sie ein Objekt zu einer Tabelle hinzufügen?
Wenn Sie Lua in einer benutzerdefinierten Anwendung ausführen, wie ich es seit Ihrer C-Codierung erraten kann, schlage ich vor, dass Sie den Allokator durch den kleinen Wertzuordner von Loki ersetzen. Dadurch wurden meine Speicherzuweisungen um mehr als das Hundert reduziert. Dies verbesserte die Leistung, indem Rundum-Reisen zum Kernel vermieden wurden, und machte mich zu einem viel glücklicheren Programmierer:)
Wie auch immer, ich habe andere Allokatoren ausprobiert, aber sie waren allgemeiner und bieten Garantien, die Lua-Anwendungen nicht nützen (wie Thread-Sicherheit und große Objektzuteilung, etc ...), und schreiben auch Ihren eigenen Small-Object-Allokator kann eine gute Woche des Programmierens und des Debuggens sein, um genau richtig zu gehen, und nach dem Suchen nach einer verfügbaren Lösung war Lokis Zuordner der einfachste und schnellste, den ich für dieses Problem gefunden habe.
Tags und Links optimization lua