Página 1 de 2

Array - AADD() vai ficando lento.

Enviado: 06 Ago 2023 16:53
por clodoaldomonteiro
Olá!

Sempre uso array para diversos processos nos meus sistemas e sempre me deparo com uma situação interessante, é que a medida em que vou adicionando registros na Array, o processamento vai ficando lento. Uns 15 mil registros vc já ver a lentidão.

Fico imaginando o pq da situação, mas vi que não tem como ao criar a array, reservar espaço pra ela ou coisa parecida.

Sei que tem como criar um DBF temporário em memória RAM e até fazer uma classe pra isso, com ajuda do Quintas, é claro (rs), mas é difícil aceitar a vitória da máquina (ela quase sempre vence, hehe).

Desde já fico grato pela a ajuda de todos.
Abraços.

Array - AADD() vai ficando lento.

Enviado: 06 Ago 2023 18:49
por JoséQuintas
Acho que array não é pra abusar.
Quando se refere a adicionar, está considerando também pesquisa ou apenas a operação de AAdd() ?

Talvez ADO, talvez multithread pra fazer o processo em separado, talvez indexação diferente.

Já usei o seguinte esquema:
Ao invés de adicionar tudo no array, adicionar apenas o RecNo().
A partir do Recno() dá pra obter todas as informações diretamente do registro, sem ocupar espaço extra no array.
Ou até temporário no mesmo esquema.
Desse jeito o array além de menor fica mais rápido.

É identificar a parte que deixa lento e tentar agilizar.

Nessas horas, dá até pra usar um MySQL só pra coisa temporária, isso seria contar com a ajuda de uma máquina adicional pra processamento.
Ou SQLite, ou Access, ou alguma outra coisa qualquer.

Não é só porque usa harbour que precisa fazer tudo com ele.

Array - AADD() vai ficando lento.

Enviado: 06 Ago 2023 20:42
por Itamar M. Lins Jr.
Olá!
No Harbour eu uso com muito mais registros, e não degrada.
Tem que ver se é um problema do xHarbour.
DBF com muitos registros deleted aumenta a lentidão um PACK pode ajudar.
Precisa ver a sua forma de fazer o processo, se tem como otimizar.
Mas 15 mil não vejo como muito não. A forma como ler o DBF e joga no array é que pode ser o problema.

Saudações,
Itamar M. Lins Jr.

Array - AADD() vai ficando lento.

Enviado: 06 Ago 2023 21:13
por JoséQuintas
Itamar M. Lins Jr. escreveu:Precisa ver a sua forma de fazer o processo, se tem como otimizar.
Mas 15 mil não vejo como muito não. A forma como ler o DBF e joga no array é que pode ser o problema.
Tá aí, até deu uma idéia pra teste:
O mesmo processo, sem fazer o aadd() no array.
Se mesmo assim ficar lento, fica comprovado que o problema não é o array.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 08:44
por ivanil
Na medida que a array fica maior, o tempo fica maior, mas esta visibilidade depende da característica de sua máquina, veja o caso abaixo: nem cocegas fez para uma array de 1 milhão de elementos.
Já a segunda rodada, aumentei para 10.000.000, saltou para 00:00:21, então foi quase que imperceptível.

Maquina: i7-64 memo 16 proc.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 10:32
por clodoaldomonteiro
Bom dia.
JoséQuintas escreveu:Acho que array não é pra abusar.
Quando se refere a adicionar, está considerando também pesquisa ou apenas a operação de AAdd() ?

Talvez ADO, talvez multithread pra fazer o processo em separado, talvez indexação diferente.

Já usei o seguinte esquema:
Ao invés de adicionar tudo no array, adicionar apenas o RecNo().
A partir do Recno() dá pra obter todas as informações diretamente do registro, sem ocupar espaço extra no array.
Ou até temporário no mesmo esquema.
Desse jeito o array além de menor fica mais rápido.

É identificar a parte que deixa lento e tentar agilizar.

Nessas horas, dá até pra usar um MySQL só pra coisa temporária, isso seria contar com a ajuda de uma máquina adicional pra processamento.
Ou SQLite, ou Access, ou alguma outra coisa qualquer.

Não é só porque usa harbour que precisa fazer tudo com ele.
Estou só adicionando mesmo:

Código: Selecionar todos

                  AAdd( aDados, {;
                   mCodigo,;
                   HB_AnsiToOem( rs:Fields( 8 ):Value ),;
                   '',;  //Portaria
                   '',;  //Descricao
                   '';
                   })

Também acho que não devemos abusar de Array com xHarbour. Tem no Delphi uma classe "TArray", em que podemos reservar memória pra a array, seria algo nesse sentido.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 10:39
por clodoaldomonteiro
Itamar M. Lins Jr. escreveu:Olá!
No Harbour eu uso com muito mais registros, e não degrada.
Tem que ver se é um problema do xHarbour.
DBF com muitos registros deleted aumenta a lentidão um PACK pode ajudar.
Precisa ver a sua forma de fazer o processo, se tem como otimizar.
Mas 15 mil não vejo como muito não. A forma como ler o DBF e joga no array é que pode ser o problema.

Saudações,
Itamar M. Lins Jr.
Como está só adicionando registros na array, acho que é o limite, pois estou lendo um arquivo .xlsx, com "CreateObject( "ADODB.Connection" )", até aí é muito rápido e depois passando os fields para uma array, para analizar esses dados.

É como isso é recorrente pra mim, ficamos com esperança de ter uma evolução no Harbour pra trabalhar com array, como já teve no clipper que tinha um limite máximo de 64KB, e tínhamos que um lib de terceiro pra contornar o problema e ainda, esse problema que tinha em outras linguagens, foi corrigido criando outras Classes para trabalhar com array.

Valeu a dica.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 10:46
por clodoaldomonteiro
Sim, Ivanil, bem rápido mesmo, e uma coisa q faço é usar um Gauge em tela, a cada 50 registros, e sabemos que quando usamos o Ecrã, o tempo cai muito.

Valeu a dica.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:01
por JoséQuintas
clodoaldomonteiro escreveu:Sim, Ivanil, bem rápido mesmo, e uma coisa q faço é usar um Gauge em tela, a cada 50 registros, e sabemos que quando usamos o Ecrã, o tempo cai muito.
Atualize a cada 1 segundo, e não a cada 50 registros.
Atualizar tela demora, comparar tempo não.

Código: Selecionar todos

IF cTimeAnt != Time()
   cTimeAnt := Time()
   // atualiza gauge aqui
ENDIF

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:02
por Itamar M. Lins Jr.
Olá!

Se fizer o processo sem usar nada, acredito que vai acontecer o problema.
Apenas DO WHILE SKIP ou FOR NEXT... LENDO a PLANILHA VIA ADO vai acontecer a lentidão.
Não tem nada a ver com AADD... Comente a linha //AADD e veja
Verifique isso para confirmar essa suspeita.

Saudações,
Itamar M. Lins Jr.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:11
por Itamar M. Lins Jr.
Olá!
acho que é o limite, pois estou lendo um arquivo .xlsx
Não tem isso no Harbour. O LIMITE é controlado pelo WINDOWS.
ficamos com esperança de ter uma evolução no Harbour pra trabalhar com array,
Não existe esse limite no Harbour, esse limite é do sistema operacional.
Pode usar MeuArray:={1000000}, a função afill() preenche o array... e verifique que é muito rápido.

Lembre-se que está manipulando um arquivo do EXCEL e ele não é rápido e se está aberto mais de 1 vez etc...
ADO vc não tem controle, pode está aberto pelo excel ou sei lá mais o quê que abre junto quando usa ADO em planilhas.

Saudações,
Itamar M. Lins Jr.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:12
por JoséQuintas
Ler a planilha por ADO é igual usar ADO com qualquer base SQL.
Pode demorar alguns segundos o SELECT, mas o acesso depois disso é instantâneo.
O acesso NÃO É registro a registro.

ADO com MySQL:

Código: Selecionar todos

SELECT * FROM....
ADO com Excel:

Código: Selecionar todos

SELECT * FROM ...
Aliás.... dependendo do que coloca no array, poderia fazer direto pelo ADO mesmo.
Mas aí entra particularidade: será que no XHarbour funciona igual no Harbour ?

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:27
por Itamar M. Lins Jr.
Olá!
Ler a planilha por ADO é igual usar ADO com qualquer base SQL.
Ler é uma coisa, mover ponteiro é outra.
EXCEL não é MySQL.
Quando usa ADO em PLANILHA DO EXCEL, tem FORMULAS, ETC... Não é um retorno de um SGBD.

Saudações,
Itamar M. Lins Jr.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:36
por JoséQuintas
Itamar M. Lins Jr. escreveu:Ler é uma coisa, mover ponteiro é outra.
EXCEL não é MySQL.
Quando usa ADO em PLANILHA DO EXCEL, tem FORMULAS, ETC... Não é um retorno de um SGBD.
Você não usa ADO, está apenas SUPONDO como funciona.

Acho que dá pra comparar o temporário do ADO com MDB/ACCESS.
Uma vez feito o SELECT, o ADO trás tudo da planilha para esse temporário.
A partir daí, nada mais a ver com Excel, vai ser o temporário.
O mesmo referente a MySQL e outras bases.

Explicação teórica, sei lá se o recordset é formato Access, ou se é array, ou outra coisa.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:40
por Itamar M. Lins Jr.
Olá!
Você não usa ADO, está apenas SUPONDO como funciona.
Uso pouco. Mas uso.
Não é problema do aadd(). Só com 15 mil registros isso "no equizist"

Saudações,
Itamar M. Lins Jr.