#1708 closed defect (fixed)
Uso de RAM en TOL: Asignación de nombres
Reported by: | Pedro Gea | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | highest | Milestone: | Mantainance |
Component: | Kernel | Version: | 3.1 |
Severity: | critical | Keywords: | |
Cc: |
Description
Al crear nuevas variables, se aprecia un aumento en el uso de memoria RAM en función de lo poco comunes que sean sus nombres.
Si creamos un gran número de reales con nombres aleatorios la RAM utilizada crece enormemente, mientras que eso no ocurre si tienen el mismo nombre.
A continuación indico un código en el que se generan dos conjuntos de nombres, uno con caracteres obtenidos al azar y otro con un mismo carácter repetido:
Real RandInteger(Real min, Real max) { Floor(Rand(min,max+1)) }; Set _RandCharacter.Set = Characters("abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"); Text RandCharacter(Real void) { _RandCharacter.Set[RandInteger(1,53)] }; Text RandName(Real length) { SetSum(For(1, length, Text (Real i) { RandCharacter(?) })) }; // Generación de nombres: Set names = For(1, 10000, Set (Real i) { [[ Text RandName(32), Text Repeat("A", 32) ]] });
Si utilizamos estos nombres para crear un conjunto de números reales con nombre obtenemos que usando el primer nombre:
Set For(1, 10000, Set (Real i) { Set [[ Real Eval("Real "<<names[i][1]<<" = 1") ]] });
la RAM incrementa en 325 MB.
Mientras que usando el segundo:
Set For(1, 10000, Set (Real i) { Set [[ Real Eval("Real "<<names[i][2]<<" = 1") ]] });
lo hace en unos 7 MB.
Este resultado no depende del mecanismo utilizado para asignar le nombre, obteniéndose idénticos resultados al usar la función PutName
:
Set For(1, 10000, Set (Real i) { Real one = 1; Set [[ Real PutName(names[i][ <1|2> ], one) // 1 ó 2 según el caso ]] });
Change History (16)
comment:1 Changed 12 years ago by
comment:2 Changed 12 years ago by
Una vez aislado este problema seguro que no cuesta mucho resolverlo. A ver si la semana que viene puedo mirarlo.
comment:3 Changed 11 years ago by
Status: | new → accepted |
---|
comment:9 Changed 11 years ago by
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
(In [5972]) New release VERSION_BUILD "b019"
Fixes #1708
Fixes #1659
BStackManager has been rewritten using google hash
BUserFunction::Evaluator doesn't clears local names of arguments because there are new instances that will be removed from stack
Argument from_UF of BGrammar::EvaluateTree must be set to true just when called from BUserFunction::Evaluator to avoid to clean the stack too soon
PutName doesn't call to BGrammar::DelObject nor BGrammar::AddObject, it just changes the name and the local or global hash by means of a new method BGrammar::ChangeName
comment:10 Changed 11 years ago by
Como consecuencia de los cambios realizados para resolver este ticket se ha precisado cambiar el comportamiento de PutName (ver #1659) y ahora ya no funcionan cosas que antes sí iban pero que eran absurdas, como
Real { Real a = 1; Real PutName("b",a); a }
NOTA: ¡Es necesario actualizar a los paquetes BysMcmc.7.3 y GuiTools.3.7 para usarlos con tol 3.2 b019! , puesto que en ambos paquetes existían usos indebidos de PutName.
comment:11 Changed 11 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:12 Changed 11 years ago by
Aunque había pasado los tests estándar hay cosas del paquete GuiTools que no funcionan, así que reabro el ticket.
Se recomienda no recompilar TOL por el momento.
comment:15 Changed 11 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
(In [5976]) Fixes #1708
Refs #1659
Last changes related to PutName are incompatible with some abusive uses of this function in some packages as GuiTools or MMS.
The StackManager can use the google hash instead of old n-ary tree, but symbols are not removed from hash table and can be used with the old name after a call to PutName in a local scope.
The rest of changes out of StackManager has been reverted
El abuso de memoria es debido a la pila local (
BStackManager
) y su diccionario, que genera árboles de nodos según las distintas letras del nombre.Cuando el conjunto de ramas para un nombre es generado, se conserva, no se destruye tras su uso. Es por ello que si se reutiliza el mismo nombre, no supone un aumento en el uso de RAM.
Esta cantidad de RAM utilizada por la pila local es mucho mayor de la esperada. En un ejemplo concreto de una previsión de MMS que utiliza 1250 MB de RAM, al menos 350 de ellos se debe a este problema causado por los distintos nombres locales de los objetos creados.