Página 2 de 2

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:42
por clodoaldomonteiro
Bom, vou ajustar e tirar Array, fazer com DBF mesmo, é ir se desprendendo aos poucos do que atrapalha nos processamentos e usando outras maneiras suportada pela linguagem.

É o fato que, array não é pra isso, e até não tem evolução como tem em outras linguagens.

Obrigado pelo interesse de todos.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 11:53
por JoséQuintas
O ADO tem uma função que transforma tudo em array de uma vez, mas se não pega todas as informações, só vai atrapalhar.
anp.png
Aproveitei pra fazer a importação mensal das tabelas da ANP que vém em Excel.
Uma delas tem mais de 100.000 registros.
Como é uma vez por mês, demorar alguns minutos acho aceitável.

O que não mencionou é sobre o quanto é esse tempo de demora, se são segundos, minutos, ou horas.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 12:38
por Itamar M. Lins Jr.
Olá!
Bom, vou ajustar e tirar Array, fazer com DBF mesmo, é ir se desprendendo aos poucos do que atrapalha nos processamentos e usando outras maneiras suportada pela linguagem.

É o fato que, array não é pra isso, e até não tem evolução como tem em outras linguagens.
E array é para que então ?
Se usando array está lento, imagine DBF.
Agente escreve uma coisa vc escreve outra... Ai fica difícil.
Mostre AQUI o problema. O Ivanil já demonstrou com milhares de registro a criação de array...
Não inventa problema onde não existe.
Até agora não tem como constatar seu problema, e não passa de reclamação inútil. Parece que não quer resolver.
É o fato que, array não é pra isso, e até não tem evolução como tem em outras linguagens.
Explica para nós o que é essa evolução ?

Saudações,
Itamar M. Lins Jr.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 13:08
por JoséQuintas
Clodoaldo, tente fazer testes isolados.
Por exemplo:

Código: Selecionar todos

AAdd( aDados, {;
   mCodigo,;
   HB_AnsiToOem( rs:Fields( 8 ):Value ),;
   '',;  //Portaria
   '',;  //Descricao
   '';
    })
Crie uma rotina só com isso pra medir tempo, colocando string qualquer e FOR/NEXT.
Depois a mesma com essa conversão.
Vai eliminando possibilidades.

De repente, se for XHarbour lento... aí vai Harbour.

Mas tudo depende de teste, no momento não dá pra dizer o que causa lentidão.
De repente tá pensando que é uma coisa, mas é outra.
O teste acima é relativamente simples de fazer.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 13:13
por JoséQuintas
teste.png
Na minha máquininha velha.... menos de 1 segundo.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 13:19
por JoséQuintas
Fugindo do tópico um pouco, mas tem a ver com o teste:
Olhem que coisa interessante...
teste.png
Fiz o primeiro teste, tudo certo.
Fui fazer outro teste aumentando a quantidade, o antivírus da Microsoft bloqueou !!!!!

O antivírus deve ter lembrado do tamanho do EXE, e viu que tá diferente.

Não se pode nem fazer teste sossegado..... kkkkk

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 13:33
por JoséQuintas
Esqueçam ESSE teste isolado.
Não serve de referência, porque não é a mesma coisa.
Tem que ser outro diferente.

Array - AADD() vai ficando lento.

Enviado: 07 Ago 2023 19:52
por carlos_dornelas
Clodoaldo, quase nada a ver com o tópico... mas estou precisando fazer exatamente o que você já diz estar fazendo:
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.
Poderia compartilhar aqui a rotina de utilizas para ler um arquivo .xlsx ? ou enviar no meu email: acd002020@gmail.com

PS: sobre o consumo de memória no xharbour com array, já me aconteceu uma vez o seguinte: dentro de um FOR NEXT eu utilizava o DECLARE para reiniciar/zerar uma matriz. Isso ia consumindo memória a cada ciclo, a ponto de travar a aplicação. Não sei se pode ser o seu caso...

Grato

Antonio Carlos
Curitiba PR

Array - AADD() vai ficando lento.

Enviado: 08 Ago 2023 13:27
por marcosgambeta
Itamar M. Lins Jr. escreveu: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.
Clodoaldo,

Penso como o Itamar.

Seu problema poderia estar na leitura do recordset e não no uso de arrays.

As rotinas de array do Harbour são escritas em C e são bem rápidas e eficientes.

Então, mudar o DESTINO (array) não vai ajudar se o problema estiver na ORIGEM (recordset).

Se pesquisar, no Google, por "ado recordset slow", vai se deparar com casos e mais casos envolvendo problemas de desempenho.

Seria possível mostrar como está criando o recordset ?

Array - AADD() vai ficando lento.

Enviado: 09 Ago 2023 18:30
por alxsts
Olá!
clodoaldomonteiro escreveu:vi que não tem como ao criar a array, reservar espaço pra ela ou coisa parecida
Com a Função Array(), é possível criar a variável com o número desejado de dimensões e ocorrências por dimensão:

Código: Selecionar todos

Examples

     .  This example creates a one-dimensional array of five elements
        using the ARRAY() function, and then shows the equivalent action by
        assigning a literal array of NIL values:

        aArray := ARRAY(5)
        aArray := { NIL, NIL, NIL, NIL, NIL }

     .  This example shows three different statements which create the
        same multidimensional array:

        aArray := ARRAY(3, 2)
        aArray := { {NIL, NIL}, {NIL, NIL}, {NIL, NIL} }
        aArray := { ARRAY(2), ARRAY(2), ARRAY(2) }

     .  This example creates a nested, multidimensional array:

        aArray := ARRAY(3, {NIL,NIL})

Código: Selecionar todos

Proc Main()

   LOCAL aArray := Array( 1000, 3 )

   CLS

   hb_alert( aArray[1000, 3 ] )   // NIL

RETURN

Array - AADD() vai ficando lento.

Enviado: 12 Ago 2023 08:34
por clodoaldomonteiro
Bom dia a todos.

Achei o problema, era um AScan() que estava usando numa linha anterior do código.

No Clipper usava array com a FAST.LIB, por conta do tamanho e busca mais rápida, e como no código ainda tem muita coisa da época do clipper, me deparo as vezes com issso. Mas é fato passado já.

Obrigado a todos.

Array - AADD() vai ficando lento.

Enviado: 12 Ago 2023 08:57
por clodoaldomonteiro
carlos_dornelas escreveu:Clodoaldo, quase nada a ver com o tópico... mas estou precisando fazer exatamente o que você já diz estar fazendo:
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.
Poderia compartilhar aqui a rotina de utilizas para ler um arquivo .xlsx ? ou enviar no meu email: acd002020@gmail.com

PS: sobre o consumo de memória no xharbour com array, já me aconteceu uma vez o seguinte: dentro de um FOR NEXT eu utilizava o DECLARE para reiniciar/zerar uma matriz. Isso ia consumindo memória a cada ciclo, a ponto de travar a aplicação. Não sei se pode ser o seu caso...

Grato

Antonio Carlos
Curitiba PR
Sim Antonio, segue adiante...

Código: Selecionar todos

////////////////////////////////////////////////////////////////////////////////
//Links úteis
// Link para Excel: http://fivewin.com.br/index.php?/topic/21673-usando-o-createobject-excelapplication/
// Link instalar Access: https://learn.microsoft.com/en-us/answers/questions/296080/how-to-fix-microsoft-ace-oledb-12-0-provider-is-no
// Tem muita coisa aqui no Forum sobre o assunto



Begin sequence
   ...
   ...

   //Planilha a abrir
   mArq_ := 'c:\minha Pasta\Planilha.xlsx'

   TRY   //Cria um objeto de conexão

      oConexao := CreateObject( "ADODB.Connection" )

   CATCH oError
      wvw_messagebox( , 'ERRO...: TER/008'+CRLF+;
       'Aviso..:O MS.Excel não esta Ativado ou Não instalada nesse Computador.'+CRLF+;
       'Instale o MS Excel para continuar com a exportação dos dados.'+CRLF+;
       cl_getError(oError),;
       MB_OK|MB_ICONERROR )
      //lOk:=.f.
      Break
   END

   //Abrindo a PLanilha
      If ".XLSX" $ Upper(mArq_)
         oConexao:ConnectionString := ;
          [Provider=Microsoft.ACE.OLEDB.12.0;Data Source=] + mArq_ +;
          [;Extended Properties="Excel 12.0 Xml; HDR=Yes";] //IMEX=1";]
       Else
         oConexao:ConnectionString := ;
          [Provider=Microsoft.Jet.OLEDB.4.0;Data Source=] + mArq_ +;
          [;Extended Properties="Excel 8.0; HDR=Yes";]
       Endif

   TRY

      oConexao:Open()

   CATCH oError  //Aqui vc pode colocar suas mensagens e rotinas de erros
      msg := 'ERRO...: FUS/009'+CRLF
      msg += 'Aviso..:Não consegui abrir a planilha (XLS) SICONFI na pasta: ' + mArq_ + CRLF
      msg += cl_getError(oError, .t.)
      MsgError( msg, .t.)
      lOk:=.f.
      Break
   END

   //Abrindo a Sheet, fazendo um Select, padrão SQL
   TRY

      rs := oConexao:Execute( "SELECT * FROM ['MinhaPasta$']" ) //vc deve colocar o no da pasta sucedido de um "$"

   CATCH oError
      wvw_messagebox( , 'ERRO...: TER/030'+CRLF+;
       'Aviso..:Não consegui abrir a primeira da planilha de Receitas do STN: ' + mArq_ + CRLF+;
       'Verifique se na planilha selecionada existe a Pasta.'+CRLF+;
       cl_getError(oError),;
       'ATENÇÃO! '+UserName, MB_OK|MB_ICONERROR )
      //lOK:=.f.
      Break
   END

   aDados:={}
   Do While !rs:Eof() .and. poe_gauge()

      IF IN_KEY()=K_ESC 		                            // se quer cancelar
         msg:='Deseja encerrar a operação?'
         IF MsgYesNo( msg )
            BREAK                                         // confirmou...
         ENDIF
      ENDIF

      If !Empty( rs:Fields( 7 ):Value ) //a primeira coluna da planilha começa com "0" na resultado do Select. A coluna "A" vai ser "0", a "B" vai ser "1" ...

         //ajustes que faço na minha rotina
         mCodigo := Left(StrTran( AllTrim( Str( rs:Fields( 7 ):Value ) ), '.', ''), 8)

         mDescricao := StrTran(HB_AnsiToOem( rs:Fields( 10 ):Value ), Chr(10), '')
         mDescricao := AllTrim(StrTran(mDescricao, Chr(13), ''))
         mDescricao := AllTrim(StrTran(mDescricao, CRLF, ''))

         mNorma := StrTran(HB_AnsiToOem( rs:Fields( 11 ):Value ), Chr(10), '')
         mNorma := AllTrim(StrTran(mNorma, Chr(13), ''))
         mNorma := AllTrim(StrTran(mNorma, CRLF, ''))

         //Adicionando resultados na Array
         AAdd( aDados, {;
          mCodigo,;
          HB_AnsiToOem( rs:Fields( 8 ):Value ),;
          HB_AnsiToOem( rs:Fields( 9 ):Value ),;   //Portaria
          mDescricao,;                             //Descricao
          mNorma;
          })

         //Se tiver passando dados pra um DBF:
         If "Condições"
         
            Append Blank
            
            Field->campo1 := rs:Fields( 0 ):Value
            Field->campo2 := rs:Fields( 1 ):Value
            Field->campo3 := rs:Fields( 2 ):Value
            
         Endif

      Endif

      rs:MoveNext()  //Vai pro próximo registro

   Enddo
   rs:Close() //Fecha o Select

   oConexao:Close()  //Fecha Cnexão

End Sequence
//Não fiz o testa da rotina acima, mas qq erro basta poucos ajustes.
//Agumas funções que uso no exemplo, vc pode substituir por outras.
Abraços