Clipper On Line • Ver Tópico - Trabalhando com ARRAY em vez de DBFCDX

Trabalhando com ARRAY em vez de DBFCDX

Projeto Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

 

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor Ladinilson Sousa » 11 Dez 2019 22:57

Boa noite caros,

Possuo um software de sorteio de bingos e para quantidades de cartelas baixo até 30.000 esta tudo muito bom. Mas agora me vejo diante de um desafio muito maior e 500.000 cartelas de teste se tornou lento para trabalhar com DBFCDX diretamente e já testados vários tipo de soluções como:

ORDWILDSEEK()
SET FILTER MEMORY ADDITIVE
SEEK
SET RELATION
ORDSCOPE()

Então tive a última cartada para array na esperança de ser mais rápida e me deparei com algumas dificuldades neste setor que pouco uso.
A ideia é pegar informações do banco de dado original e somente retornar ao mesmo quando alguma cartela já sorteada acontecer.

Comecei com...

PRIVATE aCartelas := {" "," "," "}
SELECT Cartelas
Cartelas->(DBGOTOP())
DbEVal({||AADD(aCartelas,{ALLTRIM(STR(Cartelas->numero)),Cartelas->seqcar,STR(Cartelas->falta)})})

com informações por exemplo...

NUMERO______SEQUENCIA__________________________________________________FALTA
33349________04 07 08 09 11 12 20 22 24 25 33 34 35 40 46 50 51 52 56 59_________20

onde:

NUMERO = Numero da cartela
SEQUENCIA = Sequencia de 20 de numeros da cartela
FALTA = Número de que iá indicar se estará armada ou sorteada (diminuir a cada número encontrado em SEQUENCIA)

A rotina é a cada bola sorteada ele procura se esta contido em SEQUENCIA, caso sim, ele diminui um valor em FALTA (ou seja o valor é substituido no array) isso em cada um elemento de aCartelas

Caso um FALTA esteja com valor 1, ele soma 1 a uma variavel ARMADAS
Caso FALTA fique 0 (zero) atribui-se .T. (verdadeiro) a uma variável GANHOU e atribui-se a uma variável GNUMERO do NUMERO e neste momento darei um SEEK gnumero no campo número do DBFCDX e marcarei o registro (cartela) como sorteada.

Rotina essa dentro de um...
FOR a := 1 TO LEN(aCartelas)
....
NEXT

Parece ser simples mas as sintaxes me fogem a lógica no momento e acredito para experts em arrays isso já deve ser bem simples.

Obrigado pela atenção

Ladinilson Sousa

FWH 13.12/xHarbour/Pelles C/DBFCDX/MySQL
Ladinilson Sousa
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 35
Data de registro: 09 Fev 2015 10:41
Cidade/Estado: Belém/PA
Curtiu: 1 vez
Mens.Curtidas: 0 vez

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 12 Dez 2019 20:12

me veio na cabeça:

UPDATE CARTELAS SET FALTA=FALTA-1 WHERE NUMEROS LIKE '%01%'
SELECT * FROM CARTELAS WHERE FALTA = 0

problemão, em SQL com solução simples... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor Ladinilson Sousa » 12 Dez 2019 23:00

José Quintas verdade!

Mas lembrando que os mesmos comandos "varrem" o banco de dados e em se tratando de grandes volumes, a perda de performance pode ser bem significativa pois ha a atualização (COMMIT) ainda.

Em DBFCDX um "$" (está contido) e bem rápido usando-se o SET INDEX MEMORY ADDITIVE mas o problema persiste na hora da atualização dos campos de cada registro filtrado.

Um REPLACE ALL semelhante ao UPDATE no sql parace que o programa travou rsrs
Ladinilson Sousa
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 35
Data de registro: 09 Fev 2015 10:41
Cidade/Estado: Belém/PA
Curtiu: 1 vez
Mens.Curtidas: 0 vez

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 13:33

Mas 500.000 cartelas de bingo.... se for 1 real cada... isso dá meio milhão de reais.

Tem outra coisa:

Se o processamento for no terminal, a quantidade de cartelas vai ser pequena.
Se o processamento for no servidor... aí precisa demorar menos do que o sorteio de cada bola.
Se o servidor pegar o resultado pronto dos terminais, vai ter menos processamento, porque fica tudo distribuído.

E mais outra: sei lá como fazer em multithread, mas....

Se houver um processo fazendo em ordem das que faltam menos... o resultado, que é o mais importante, estaria pronto antes do processo completo terminar, e nem notariam a demora do processo restante.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 13:39

Não sei também se ir limpando o array agiliza, pra ter menos números pra processar....
Sempre daria pra pesquisar os números completos pelo número da cartela, então deixa de ser importante trabalhar sempre com todos os números.
Só não sei se o tempo do hb_ADel() vai compensar o ganho de tempo. (no caso de array), ou o tempo de limpar a string no DBF (numero $ trim( falta ) ).

Vai ter que fazer os testes.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 13:44

Também vários arrays...

Um array para as cartelas que faltam 1 número, outro pra 2, etc. e transferindo de um para o outro.

Imagino assim:
sorteou uma bola.... o urgente é analisar os que só faltavam 1 bola, os demais não tem pressa.
as cartelas que faltam 2 números nunca vão fazer bingo antes das que faltam 1 só número...
As demais... sem pressa de trazer o resultado.

Acho que vai ser impossível as 500.000 cartelas esperando um único número....
Se forem distribuídos de forma igual, poderia reduzir em 100 vezes.... 5.000 cartelas esperando um único número.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 14:13

Acho que estou a 1000 por hora hoje.... kkkk
Pensei num trem doido pra última opção:

PROCEDURE Main

   LOCAL aList := {}
   
   FOR EACH aFalta IN aList DESC
      FOR EACH aNumeros IN aFalta DESC
         lAcertou := .F.
         FOR EACH nNumero IN aNumeros
            IF nNumero:__EnumIndex != 1
               IF nNumero == nSorteio
                  hb_Adel( aNumeros, nNumero:__EnumIndex, .T. )
                  lAcertou := .T.
                  EXIT
               ENDIF
            ENDIF
         NEXT
         IF lAcertou
            AAdd( aFalta[ aFalta:_EnumIndex - 1 ], aNumeros )
            hb_ADel( aFalta[ aFalta:_EnumIndex ], .T. )
         ENDIF
      NEXT   
      IF aFalta:__EnumIndex < 2 .AND. Len( aFalta[ 1 ] ) != 0
         // alguém ganhou
      ENDIF
   NEXT

   RETURN


É um array geral, com um array pra cada quantidade faltante.
Cada array interno vai ter o número da cartela, e os números que faltam, por isso pula o 1 na checagem de números
Cada número acertado retira o número da lista da cartela, e move a cartela pro array "anterior"
O array 1 seria dos que fizeram bingo, então... assim que processa o array 2 dos que estão pra bater, se existir elemento no array 1 já indica que alguém bateu.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 14:19

E nem precisa se preocupar com array ZERO....
Quem já acertou todos os números... não vai acertar mais nenhum.... então nunca vai mover do 1 pro ZERO.

O sorteio das primeiras bolas vai ser o mais demorado, mas vai agilizando a cada bola sorteada, porque vão ser menos números pra fazer teste.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 14:26

Outra idéia pro SQL: ter 100 campos com S ou N, um pra cada número, e índices também para os 100 campos, para o falta, e para o número da cartela

UPDATE TABELA SET FALTA = FALTA - 1, NUMERO10='X' WHERE NUMERO10 = 'S'
SELECT * FROM TABELA WHERE FALTA = 0

Desta forma, o SELECT e o UPDATE vão ser em 5.000 cartelas, e não nas 500.000
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor Ladinilson Sousa » 13 Dez 2019 15:22

José Quintas

Fiz um estudo e a solução foi simples até depois de procurar sintaxes e sintaxes.

"As vezes o menos é mais!"

    PRIVATE aCartelas := {" "," "," "}

    SELECT Cartelas
    Cartelas->(DBGOTOP())   
    DbEVal({||AADD(aCartelas,{ALLTRIM(STR(Cartelas->numero)),Cartelas->seqcar,STRZERO(Cartelas->falta,2)})})
    Cartelas->(DBGOTOP())

   FOR s := 1 TO LEN(aCartelas)
         n:= aCartelas[s][1]
         q:= aCartelas[s][2]
         f:= VAL(aCartelas[s][3])
        IF AT(STRZERO(Bolanumero,2),q) > 0
            f := VAL(f)-1
            aCartelas[s][3] := STRZERO(f,2)
       ENDIF
       IF f < vnFalta
          carma++
       ENDIF   
   IF f == 0
       vbateu := .t.
       SELECT Cartelas
       Cartelas->(DBGOTOP())
       Cartelas->(ORDSETFOCUS("numero"))
       Cartelas->(DBGOTOP())
       SEEK n
           Cartelas->sorteou := nPremio
           Cartelas->falta   := f
     ENDIF   
    NEXT   



Velha e simples sintaxe mas funcional rsrsr

Bom final de semana para senhor!

Obrigado
Ladinilson Sousa
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 35
Data de registro: 09 Fev 2015 10:41
Cidade/Estado: Belém/PA
Curtiu: 1 vez
Mens.Curtidas: 0 vez

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor JoséQuintas » 13 Dez 2019 15:41

se desse jeito já resolveu, pode deixar mais básico/rápido ainda e retirar os StrZero() e o At()
Os gotop são inúteis, poderia retirar também.

O at() pode ser substituído por if "texto" $ string
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18162
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Trabalhando com ARRAY em vez de DBFCDX

Mensagempor Nascimento » 17 Dez 2019 22:44

achei um link que pode ser util
https://www.linguagemclipper.com.br/dicas/arrays
A arte de programar é simplesmente fazer seus pensamentos serem interpretados por uma maquina :) clipper 5.3 /harbour/minigui
Avatar de usuário

Nascimento
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 711
Data de registro: 19 Jul 2008 12:11
Cidade/Estado: OLINDA-PE
Curtiu: 110 vezes
Mens.Curtidas: 76 vezes




Retornar para Harbour

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 3 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro