vigas viga una tributario predimensionamiento pisos para losas hormigon entre ejemplo edificio distancia dimensiones concreto como columnas calculo calcula armado ancho optimization lua

optimization - viga - ¿Cómo se predimensiona una matriz en Lua?



predimensionamiento de columnas excel (6)

Tengo un programa Lua que parece ser más lento de lo que debería ser. Sospecho que el problema es que estoy agregando valores a una matriz asociativa uno a la vez y la tabla tiene que asignar nueva memoria cada vez.

Parecía haber una función table.setn, pero falla bajo Lua 5.1.3:

stdin:1: ''setn'' is obsolete stack traceback: [C]: in function ''setn'' stdin:1: in main chunk [C]: ?

De la búsqueda en Google que hice, deduje que esta función se depreció en Lua 5.1, pero no puedo encontrar qué (si acaso) reemplazó la funcionalidad.

¿Sabes cómo precalcular una mesa en Lua?

Alternativamente, ¿hay alguna otra forma de evitar la asignación de memoria cuando agrega un objeto a una tabla?


No creo que puedas, no es una matriz, es una matriz asociativa, como un hash Perl o una matriz awk.

http://www.lua.org/manual/5.1/manual.html#2.5.5

No creo que puedas preestablecer su tamaño significativamente desde el lado de Lua.

Sin embargo, si asigna la matriz en el lado C, la

void lua_createtable (lua_State *L, int narr, int nrec);

puede ser lo que necesitas

Crea una nueva tabla vacía y la empuja a la pila. La nueva tabla tiene espacio preasignado para elementos de matriz narr y nrec elementos no de matriz. Esta preasignación es útil cuando sabe exactamente cuántos elementos tendrá la tabla. De lo contrario, puede usar la función lua_newtable.


Todavía hay un luaL_setn interno y puede compilar Lua para que quede expuesto como table.setn. Pero parece que no ayudará porque el código no parece hacer ninguna extensión previa.

(También el setn como se comentó anteriormente, el setn está relacionado con la parte de la matriz de una tabla de Lua, y dijiste que estás usando la tabla como una matriz asociativa)

Lo bueno es que incluso si agrega los elementos uno por uno, Lua no aumenta la matriz de esa manera. En cambio, usa una estrategia más razonable. Aún obtiene múltiples asignaciones para una matriz más grande, pero el rendimiento es mejor que obtener una nueva asignación cada vez.


Déjame centrarme más en tu pregunta:

agregar valores a una matriz asociativa, uno a la vez

Las tablas en Lua son asociativas, pero se optimiza el uso de ellas en forma de matriz (1..N). Tienen caras dobles, internamente.

Entonces ... Si está agregando valores asociativamente, siga las reglas anteriores.

Si usa los índices 1..N, puede forzar un reajuste de tamaño único ajustando t [100000] = algo. Esto debería funcionar hasta el límite del tamaño optimizado de la matriz, especificado en las fuentes de Lua (2 ^ 26 = 67108864). Después de eso, todo es asociativo.

ps El antiguo método ''setn'' manejaba solo la parte de la matriz, por lo que no sirve para el uso asociativo (ignore esas respuestas).

pps ¿Ha estudiado consejos generales para mantener el rendimiento de Lua en un nivel alto? es decir, conocer la creación de tablas y, en su lugar, reutilizar una tabla antes que crear una nueva, el uso de "impresión local = imprimir" y así evitar los accesos globales.


Aunque esto no responde a su pregunta principal, responde su segunda pregunta:

Alternativamente, ¿hay alguna otra forma de evitar la asignación de memoria cuando agrega un objeto a una tabla?

Si está ejecutando Lua en una aplicación personalizada, como puedo adivinar desde que hace la codificación C, le sugiero que reemplace el asignador con el asignador de pequeño valor de Loki, esto redujo mis asignaciones de memoria más de 100 veces. Esto mejoró el rendimiento al evitar viajes redondos al Kernel, y me hizo un programador mucho más feliz :)

De todos modos, probé otras distribuidoras, pero fueron más generales y proporcionan garantías que no benefician a las aplicaciones Lua (como la seguridad de subprocesos y la asignación de objetos grandes, etc.), también escribir su propio asignador de objetos pequeños puede ser una Una buena semana de programación y depuración para hacer las cosas bien, y después de buscar una solución disponible, el asignador de Loki fue el más fácil y rápido que encontré para este problema.


Si declara su tabla en código con una cantidad específica de elementos, haga lo siguiente:

local tab = { 0, 1, 2, 3, 4, 5, ... , n }

entonces Lua creará la tabla con la memoria ya asignada para al menos n elementos.

Sin embargo, Lua usa la técnica de asignación de memoria incremental 2x, por lo que agregar un elemento a una tabla rara vez obliga a una reasignación.


static int new_sized_table( lua_State *L ) { int asize = lua_tointeger( L, 1 ); int hsize = lua_tointeger( L, 2 ); lua_createtable( L, asize, hsize ); return( 1 ); } ... lua_pushcfunction( L, new_sized_table ); lua_setglobal( L, "sized_table" );

Luego, en Lua,

array = function(size) return sized_table(size,0) end a = array(10)

Como un truco rápido para ejecutar esto, puede agregar C a lua.c