close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 13 years ago

Closed 13 years ago

#1571 closed doubt (goodtrick)

Ineficiencia vinculada a la gramática de salida de una función

Reported by: Pedro Gea Owned by: Víctor de Buen Remiro
Priority: high Milestone: Mantainance
Component: Kernel Version: 3.1
Severity: critical Keywords:
Cc:

Description

En el tique #1426 ya se empezaron a tratar los problemas de eficiencia que se derivaban de la naturaleza de las gramáticas de datos (Serie o Matrix) cuando los objetos asociados eran de grandes dimensiones.

El problema de que estos objetos se traten como objetos elementales y se asignen "por copia" (en lugar de "por referencia") es una fuente de ineficiencia en la creación de variables auxiliares.

Esta cuestión podía salvarse evitando la creación de más objetos mediante el uso de conjuntos (Set) para imitar la asignación por referencia. (Véase #1431)

A continuación se plantea una situación más dificil de salvar manteniendo la interfaz de la función, ya que el problema parece residir en una copia vinculada a la devolución de la salida.

Véase el siguiente ejemplo, en el que se aprecia que el uso
de la función get.m está vinculado a un aumento en el tiempo de la llamada, por la construcción de una nueva matriz-copia para la salida.

Matrix m = Rand(10000, 1000, 0, 1);
@Matrix n = [[m]];

Matrix get.m(Real void) { m };
@Matrix get.n(Real void) { n };

Real times = 20;

Real t1 = Copy(Time);
Set For(1, times, Real (Real i) {
  MatDat(get.m(?), 1, 1)
});
Real t2 = Copy(Time);
Real t21 = (t2-t1)*1000/times; // 100 ms

Real times := 10000;

Real t3 = Copy(Time);
Set For(1, times, Real (Real i) {
  MatDat(get.n(?)[1], 1, 1)
});
Real t4 = Copy(Time);
Real t43 = (t4-t3)*1000/times; // 0.01 ms


Real t5 = Copy(Time);
Set For(1, times, Real (Real i) {
  MatDat(m, 1, 1)
});
Real t6 = Copy(Time);
Real t65 = (t6-t5)*1000/times; // 0.005 ms

Change History (1)

comment:1 Changed 13 years ago by Víctor de Buen Remiro

Resolution: goodtrick
Status: newclosed

Esto funciona tal y como yo esperaría. Si devuelves copia de objetos pesados lógicamente tarda más que si devuelves referencia.

Lo que no se puede hacer es devolver referencias sistemáticamente sin que lo indique el usuario, porque eso tendría efectos secundarios si luego se modifican los objetos devueltos porque eso es lo mismo que modificar los originales.

Note: See TracTickets for help on using tickets.