Opened 13 years ago
Last modified 13 years ago
#1426 reopened doubt
Diferencias de eficiencia según se escriba el código
Reported by: | Pedro Gea | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | highest | Milestone: | Mantainance |
Component: | Kernel | Version: | |
Severity: | critical | Keywords: | |
Cc: |
Description
Intentando corregir algunos problemas de eficiencia, me encuentro con mecanismos que duplican el tiempo que consumen algunas operaciones.
Aislando aislando he llegado a un trozo de código que no consigo entender y donde el tiempo empeñado parece depender sólo del modo en que se escribe el código.
¿Podría explicarse qué está ocurriendo? ¿puede solucionarse esa diferencia de tiempo invertido? ¿hay algunos consejos o normas de estilo que puedan aplicarse de manera general para contribuir a la eficiencia del código?
Adjunto los archivos para reproducir el ejemplo.
Attachments (4)
Change History (15)
Changed 13 years ago by
Attachment: | list3Q.tol added |
---|
Changed 13 years ago by
Attachment: | list3Q.oza added |
---|
comment:1 Changed 13 years ago by
comment:2 Changed 13 years ago by
Entiendo. Me doy cuenta de que al asignar una serie con otro nombre estoy creando una nueva copia. Probablemente esa costumbre viene heredada del trabajo con NameBlock
o Set
cuya asignación es por referencia.
El operador =
funciona de manera distinta según la gramática, en algunos casos la asignación es por valor y en otros por referencia. Cuando es por referencia, puede forzarse la copia con la función Copy
, sin embargo poco se puede hacer para forzar la asignación por valor. Quizá sólo ese artificio de usar Set
como contenedor de las referencias:
- Si quería hacer:
Serie a = ...; Serie b = a;
y quea
yb
sean el mismo objeto. - Hago:
Set a. = [[ ... ]]; Set b. = [[ a.[1] ]];
simulando que la variableSet
(con un nombre acabado en.
) es una referencia y su contenido se accede mediante el acceso a su primer elemento[1]
.
¿Podría implementarse un operador de asignación nuevo, que permita forzar esa asignación por referencia?
- Algo como:
Serie a = ...; Serie b =& a;
y quea
yb
sean el mismo objeto.
Changed 13 years ago by
Attachment: | callgrind.out.26240 added |
---|
valgrind --tool=callgrind /usr/local/tol31/bin/tolcon /tmp/list3Q.tol
Changed 13 years ago by
Attachment: | Captura-callgrind.out.26240.png added |
---|
comment:4 Changed 13 years ago by
Al principio en TOL el operador '=' era siempre de referencia y había que especificar el Copy siempre. Como resultado de una serie de parches históricos para dar respuesta a peticiones contradictorias se ha llegado al estado actual en el que cada tipo hace una cosa.
Sin embargo, en el tipo Serie
no se hace copia, así que voy a ver con el profiler de linux si entiendo exactamente qué es lo que pasa. Al tratarse de un tipo de datos virtual puede que se desencadenen acciones de más al crear un nuevo objeto, aunque éste sea referencial.
Lo del operador de referencia se puede estudiar para una próxima versión pues no es algo que se haga de un día para otro. De hecho se podría hacer otro de copia forzada y el actual se comportaría como hasta ahora para evitar problemas de compatibilidad hacia atrás.
comment:5 follow-up: 8 Changed 13 years ago by
Me parece muy interesante poder introducir estos nuevos operadores de asignación, no sé si habría que crear un nuevo tique demandándolo explícitamente. ¿Lo creamos?
Respecto al funcionamiento del operador de asignación, parece lógico que pudiera ser "por valor" para los tipos más elementales, quizá la cuestión es qué gramáticas son así de elementales, para mí por ejemplo, las matrices (Matrix
) no serían uno de ellos.
El funciamiento con series siempre me ha generado algo de duda, quizá por la doble naturaleza de las series (véase #880).
comment:8 Changed 13 years ago by
Quiero matizar que el operador de asignación en TOL es :=
, pues es el que permite asignar un nuevo valor a una variable ya existente. El signo =
es el del operador de definición pues sólo puede aplicarse para definir un objeto nuevo.
Tanto en un caso como en otro, el que funcione como copia o referencia depende actualmente del tipo de datos.
comment:9 Changed 13 years ago by
La solución propuesta en [4111] hace que vuelva a fallar el ticket #579.
El operador de definición =
en el tipo Serie
no era de copia porque no se puede copiar un objeto virtual, pero tampoco lo era de referencia desde que se pidió resolver el ticket #579. Lo que se hizo es que al expresar
Serie b = a;
internamente se aplica el operador identidad, es decir, el signo monario +
Serie b = +a;
Al eliminar ese paso el objeto 'b' es una referencia del objeto 'a' por lo que al cambiar el 'a' se cambia el 'b' y viceversa, que es lo que se pretendía evitar en #579.
Hay que volver a recuperar el comportamiento anterior porque puede haber código TOL que dejaría de funcionar.
Volveré a ver si hay alguna forma de acelerar esta pseudo-copia.
comment:10 Changed 13 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
En Dt1 y Dt3 los tiempos son casi iguales mientras que Dt2 tarda casi el doble.
La única diferencia es que en la segunda versión se está creando un objeto serie que es un objeto de cierto peso, mientras que en la primera y en la segunda se usan referencias.
Habrá que ver si es posible acelerar algo, pero lo que está claro es que si haces cosas distintas no tiene porqué tardar lo mismo.