Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-10-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Al parecer hay que tener más datos en cuenta.

Debes hacerte la pregunta: ¿Deseo tener todas esas matrices en memoria o no?

Si resulta que solo accederas a una sola matriz varias veces, lo óptimo sería tener todos los datos guardados en disco, y recuperarlos en tiempo de ejecución.

Si vas a necesitar todas las matrices, o las vas a necesitar frecuentemente, quizás debas tenerlas en memoria.

Ya sea en forma de constantes o variables, al cargar tu aplicación se cargarán todas las matrices en memoria, si son muchas matrices... estas sobrecargando el sistema.

Otra idea más, Tener cada matriz en un archivo:
L_72_F_32_1_1V.dat
L_72_F_32_1_2V.dat

En tiempo de ejecución cargas el que necesites, lo adaptas a un array dinámico y listo. Usando un Stream puede resultar mucho más cómodo (busca por el foro).

De todas formas, la migración de Clipper a Delphi no te la quita nadie. Acabo de modificar la rutina "LeerArchivo" de mi mensaje anterior para hacerlo de una forma más clara.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.

Última edición por Lepe fecha: 10-10-2007 a las 01:31:25.
Responder Con Cita
  #2  
Antiguo 10-10-2007
jplj jplj is offline
Miembro
 
Registrado: oct 2003
Posts: 189
Poder: 23
jplj Va por buen camino
Hola:

Estoy probando lo que me habeis dicho:
Código Delphi [-]
Unit datos;

interface

uses sysutils;


type
  TVector = Array of array of double;

var

 L_72_F_32_1_1V: array [0..3,0..4] of double =
   (
      ( 0,2,3,4,1 ),
      ( 1,3,4,5,3 ),
      ( 2,3,3,4,8 ),
      ( 3,2,3,4,9 )
   );

 L_72_F_32_1_2V: array [0..2,0..4] of double =
   (
      ( 1,2,3,4,1 ),
      ( 2,3,4,5,3 ),
      ( 2,3,3,4,8 )
   );

 L_72_F_32_1_3V: array [0..3,0..4] of double =
   (
      ( 1,2,3,4,1 ),
      ( 2,3,4,5,3 ),
      ( 2,3,3,4,8 ),
      ( 2,2,3,4,9 )
   );

FUNCTION proc_L_72_F_32(ns:integer; CC:String):TVector;


implementation


FUNCTION proc_L_72_F_32(ns:integer; CC:String): TVector;
begin

   if (nS = 1) AND (cC = '1V') then
      Result := L_72_F_32_1_1V
   else if (nS = 1) AND (cC = '2V') then
      Result := L_72_F_32_1_2V
   else if (nS = 1) AND (cC = '3V') then
      Result := L_72_F_32_1_3V
   end if
end;

end.

Pero al compilar me dice -lineas marcada en rojo de proc_L_72_F_32- que los tipos Array - TVector son incompatible .

He modificado la función de la siguiente forma:
Código Delphi [-]
FUNCTION proc_L_72_F_32(ns:integer; CC:String): TVector;
var
   v: TVector;
   i, h: integer;
begin


   if (nS = 1) AND (cC = '1V') then
   begin
      Setlength(v, High(L_72_F_32_1_1V)+1, High(L_72_F_32_1_1V[0])+1);
      for i:= High(v) downto Low(v) do
      begin
         for h:= High(v[i]) downto Low(v[i]) do
            v[i,h]:= L_72_F_32_1_1V[i,h];
      end;
   end
   else if (nS = 1) AND (cC = '2V') then
      Setlength(v, High(L_72_F_32_1_2V)+1, High(L_72_F_32_1_2V[0])+1);
      for i:= High(v) downto Low(v) do
      begin
         for h:= High(v[i]) downto Low(v[i]) do
            v[i,h]:= L_72_F_32_1_2V[i,h];
      end;
   else if (nS = 1) AND (cC = '3V') then
      ....
   end if

   result:= v;
end;

Con lo que en cada caso hay que "recorrer" el array para asignarselo al array dinámico.

¿Alguna forma de mejorar esto, o de realizar una asiganción "directa"?
__________________
Sonríe. Mañana puede ser peor.
Responder Con Cita
  #3  
Antiguo 10-10-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 24
Mick Va por buen camino
Aunque se pudiese realizar una asignacion directa, seria algo ineficiente porque el programa tendria igualmente que copiar los datos de una variable a otra .
La ventaja de usar directamente los datos de los arrays es que es muy rapido no se necesita nunca copiar esos arrrays de un lado a otro ya estan en memoria en su sitio una vez cargado el ejecutable.

Si necesitas la maxima eficiencia, tendrias que trabajar con punteros, aunque se puede ocultar la complejidad de usar punteros definiendo y utilizando una clase que facilite el acceso a los datos.

Todo depende de si esos arrays cambian el numero de columnas y/o filas. Si esos arrays tienen el mismo numero de columnas y filas, lo mas rapido y eficiente es usar un puntero a un array para devolver los datos, ejemplo:

Código Delphi [-]

type
  // Definimos mas filas de las que realmente pudiera tener cualquier array que inicialicemos, como accederemos despues a traves de un puntero
  // no importa que ALineas tenga muchas mas filas que los datos reales.
  ALineas= array [0..1023,0..4] of double;
  PLineas= ^ALineas;

function  proc_L_72_F_32(ns:integer; CC:String): PLineas
begin
   if (nS = 1) AND (cC = '1V') then
      Result := @L_72_F_32_1_1V
   else if (nS = 1) AND (cC = '2V') then
      Result := @L_72_F_32_1_2V
   else if (nS = 1) AND (cC = '3V') then
      Result := @L_72_F_32_1_3V
   end if
end;

function test;
va
 Ptr: PLineas;
begin

 Ptr:=  proc_L_72_F_32( ... );

 // Y Accederiamos a los datos de la siguiente manera
 Ptr^[0,3]; 
 Ptr^[1,2]; 
 Ptr^[2,3]; 
end;

Si los arrays tienen numero de filas variables, el problema es que en un array estatico no se sabe a posteriori cuantas filas tiene asi que o se usa alguna otra constate que nos lo diga (usando un tipo record por ejemplo que almacena tanto el array como el numero de filas) o se crea una ultima fila "en blanco" con algun valor numerico que nunca pueda salir en los datos reales y que marque el final.

Código Delphi [-]

 L_72_F_32_1_3V: array [0..3,0..4] of double =
   (
      ( 1,2,3,4,1 ),
      ( 2,3,4,5,3 ),
      ( 2,3,3,4,8 ),
      ( 2,2,3,4,9 ),
      ( 0,0,0,0,0 )   // cuando recorremos el array al llegar a esta fila sabemos que no hay mas
   );

Si el numero de filas y columnas varía luego es un pelin mas complejo, si realmente necesitas un sistema con todo variable (filas y columnas) , indicalo e intentare poner un ejemplo.

Saludos

Última edición por Mick fecha: 10-10-2007 a las 12:04:34.
Responder Con Cita
  #4  
Antiguo 10-10-2007
jplj jplj is offline
Miembro
 
Registrado: oct 2003
Posts: 189
Poder: 23
jplj Va por buen camino
Question

El funcionamiento del programa es el siguiente.

En un archivo prg tenemos las tablas de datos, esta tablas está agrupadas en funciones en base al tipo de datos que proporcionan. De esta forma en este archivo nos encontramos con funciones similares a:
Código Delphi [-]

FUNCTION L_72_F_32( nS, cC )  -> devuelve tablas con valores del tipo F

FUNCTION L_72_G_32( nS, cC )  -> devuelve tablas con valores del tipo G

FUNCTION L_72_HJ_32( nS, cC )  -> devuelve tablas con valores del tipo HJ

FUNCTION L_72_TM_32( nS, cC )  -> devuelve tablas con valores del tipo TM

Dentro de cada función los array tienen el mismo número de columnas, pero el número de filas varía.

Entre los arrays devuelto por diferentes funciones varía también el número de columnas.

El array devuelto por esta funciones es recuperado en una función similar a:
Código Delphi [-]
FUNCTION LeeLinea(nS, cC, cClase)
  LOCAL aDatos:= {}

  IF cClase = "F" 
     aDatos:= L_72_F_32( nS, cC ) 
  Else If cClase = "G"
     aDatos:= L_72_G_32( nS, cC )
  Else If cClase = "HJ"
     aDatos:= L_72_HJ_32( nS, cC ) 
  Else If cClase = "TM"
     aDatos:= L_72_TM_32( nS, cC ) 
  End if

RETURN aDatos

Por último una función de intrepolación trata los datos obtenidos:
Código Delphi [-]
FUNCTION IntrePolacion(cClase, nValorEntrada, nIndice, sS, c)
  LOCAL nValor:= 0;
            aDatos:= {}

   aDatos:= FUNCTION (nS, cC, cClase)

   nValor:= Interpolar(aDatos, nValorEntrada, nIndice, cClase) 

RETURN nValor

Cita:
Mick
La ventaja de usar directamente los datos de los arrays es que es muy rapido no se necesita nunca copiar esos arrrays de un lado a otro ya estan en memoria en su sitio una vez cargado el ejecutable
¿Cómo?
__________________
Sonríe. Mañana puede ser peor.
Responder Con Cita
  #5  
Antiguo 10-10-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Yo creo que nos estamos mareando demasiado. Hay tantas opciones que nos perdemos, para mí la solución más limpia sería:
Código Delphi [-]

type  TVector = Array of array of double;

function LeeLinea(nS, cC, cClase:string):TVector;
var ruta:string;
begin
  ruta := Extractfilepath(Application.Exename) + 'L_72_'+ cClase+ '_'+ns+'_'+cC+'.dat';

  Result:= CargaDatos(ruta);
end;

La rutina establece dinamicamente las columnas y las filas del array y devuelve los datos; cuando dicha variable pierda su visibilidad, delphi liberará la memoria del array, punto y final.

Nos quitamos de encima los siguientes puntos:
- el nombre de las funciones que tanto nos marea.
- los punteros que se arrastrarían por todo el programa.
- Tener en memoria todos los arrays cargados.

No estamos hablando de arrays con 1.000.000 de datos, son unos 100 o 200 que se leerán de un solo golpe del disco duro, y el tiempo en hacerlo no se notará.

Los archivos se guardarían en binario, para guardarse directamente como números floats (nos ahorramos leer como texto y convertir cada uno a número). La migración requiere un paso más, pero el resultado creo lo merece.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #6  
Antiguo 10-10-2007
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Para muestra un boton:

Saludos
Archivos Adjuntos
Tipo de Archivo: zip MemoryStream.zip (1,7 KB, 4 visitas)
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #7  
Antiguo 11-10-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 24
Mick Va por buen camino
Una forma de hacerlo con un minimo uso de memoria y rapido acceso a los datos.

Código Delphi [-]
unit uDataMatrix;

//##############################################################################
interface
//##############################################################################

uses SysUtils;

type

  TDataArray= array [0..MaxInt div 16-1] of double;
  PDataArray= ^TDataArray;

  TDataMatrix= class
     private
      FColCount,FRowCount:integer;
      FData: PDataArray;
      procedure SetData(AData:PDataArray; ARows,ACols:integer);
      function  GetCell(ARow,ACol:integer):double;
     public
      procedure Select(Model:string); overload;
      procedure Select(Family:string; nS:integer; cC:string); overload;
      property RowCount:integer read FRowCount;
      property ColCount:integer read FColCount;
      property Cells[ARow,ACol:integer]:double read GetCell; default;
  end;

var
 DataMatrix: TDataMatrix;


//##############################################################################
implementation
//##############################################################################

type
  RModel= record
    Name:string;
    Rows:integer;
    Cols:integer;
    Data:Pointer;
  end;

var

//#######################################################################
//#### Datos, cualquier nuevo modelo solo hace falta añadirlo aqui ######
//#######################################################################

L_72_F_32_1_1V: array [0..19] of double = ( 0,2,3,4,1,   1,3,4,5,3,   2,3,3,4,8,  3,2,3,4,9 );
L_72_F_32_1_2V: array [0..14] of double = ( 1,2,3,4,1,   2,3,4,5,3,   2,3,3,4,8  );
L_72_F_32_1_3V: array [0..13] of double = ( 1,2,3,4,1,3,4,  2,3,4,5,3,2,3  );
OTRFAMILY_1_3V: array [0..13] of double = ( 1,2,3,4,1,3,4,  2,3,4,5,3,2,3  );

Models: array [0..3] of RModel= (
  ( Name:'L_72_F_32_1_1V'; Rows:4; Cols:5; Data:@L_72_F_32_1_1V ),
  ( Name:'L_72_F_32_1_2V'; Rows:3; Cols:5; Data:@L_72_F_32_1_2V ),
  ( Name:'L_72_F_32_1_3V'; Rows:2; Cols:7; Data:@L_72_F_32_1_3V ),
  ( Name:'OTRFAMILY_1_3V'; Rows:2; Cols:7; Data:@OTRFAMILY_1_3V )
);

//####### Metodos ########################################################

function TDataMatrix.GetCell(ARow,ACol:integer):double;
begin
  Result:= FData^[ARow*FColCount+ACol];
end;

procedure TDataMatrix.SetData(AData:PDataArray; ARows,ACols:integer);
begin
  FData    := AData;
  FRowCount:= ARows;
  FColCount:= ACols;
end;

procedure TDataMatrix.Select(Model:string);
var
 i:integer;
begin
  for i:=High(Models) downto 0 do
   if Models[i].Name=Model then begin
      SetData( Models[i].Data, Models[i].Rows, Models[i].Cols );
      Exit;
   end;
   Raise Exception.Create('Unknow Model');
end;

procedure TDataMatrix.Select(Family:string; nS:integer; cC:string);
begin
  Select( Format( '%s_%d_%s' ,[family,nS,cC]) );
end;

//###############################################################
// Creamos un objeto para acceder a los datos (en el arranque del programa)
// Lo que sigue a continuacion se puede eliminar si queremos crear nuestros
// propios objetos en el programa solo cuando sean necesarios
initialization
begin
 DataMatrix:= TDataMatrix.Create;
end;
//###############################################################
finalization
begin
 DataMatrix.free;
end;

end.

Como usar la unit:

Código Delphi [-]
uses uDataMatrix;

// Seleccionar modelo/datos
DataMatrix.Select('L_72_F_32', 1,'3V');
// Usar los datos
for Row:=0 to DataMatrix.RowCount-1 do
  for Col:=0 to DataMatrix.ColCount-1 do
      Sum:= sum+ DataMatrix[Row,Col];
// Otra forma de seleccionar los datos que nos interesen
DataMatrix.Select('L_72_F_32_1_3V');
  
// Si no queremos usar el objeto que crea la unit al arrancar
// Podemos crear otros objetos

var
 Data:TDataMatrix;
begin
 Data:= TDataMatrix.Create; 
 try
    Data.Select('L_72_F_32',1,'3V');
    Data.RowCount;    // Numero de filas
    Data.ColCount;     // Numero de colmnas
    Data[columna,fila]; // Acceder a un dato de la matriz
    //
    Data.Select('OTROMODELO', 1,'1V');
    ..etc. 
 finally
   Data.Free;
 end;

end;

Saludos

Última edición por Mick fecha: 11-10-2007 a las 13:13:57.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
arrays dinamicos Chompiras Varios 8 14-07-2015 22:49:51
Arrays dinamicos Besto Varios 4 13-10-2006 15:24:01
Arrays dinámicos en memoria eliash OOP 5 01-02-2006 11:03:26
Arrays dinámicos con Delphi.NET mamen .NET 0 25-11-2004 14:21:35
Arrays Dinamicos mauro Varios 4 05-07-2003 21:14:29


La franja horaria es GMT +2. Ahora son las 00:57:40.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi