Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

BlackTDN :: Performance : Função Padrão vs Função de Usuário

Performance Sabemos que Performance não é um forte dos produtos TOTVS, não que a tecnologia não permita isso, mas, principalmente, porque os desenvolvedores não se preocupam muito com ela. Performance, me parece, é algo relevado a segundo, terceiro ou mesmo a nenhum plano.  Utilizam do seguinte jargão: “No que está funcionando não se mexe”.

E isso nos é custoso. Custa em tempo de CPU, custa em paciência e custa, principalmente, o nosso precioso tempo. Não basta ter um servidor “parrudo” (que normalmente é a desculpa que se dá) o sistema tem que ser funcional e, de certa forma, rápido.

Para exemplificar vou usar de duas funções, escritas em ADVPL, documentadas no TDN e de livre acesso aos usuários. SomaStr(cValor1,cValor2) : cSoma e MultStr(cValor1,cValor2) : cMult. Para confrontá-las utilizarei dos métodos Add() e Mult() da Classe tBigNumber.

No primeiro caso, SomaStr() fez páreo com o método Add() de tBigNumber apresentando diferenças insignificantes que não comprometeriam a performance do sistema no que diz respeito a utilizá-la em detrimento à função de usuário.

Já no segundo caso, MultStr() é muito custosa. Utiliza um tempo considerável de CPU e sua performance degrada exponencialmente a cada iteração. Neste caso é preferível utilizar a função de usuário ao invés da função padrão.

Utilizei, para o exemplo, SomaStr() e MultStr() mas poderia utilizar qualquer outra função ou programa (principalmente de relatório).

Aos Dados:

Para SomaStr()

tBigNumber:ADD x SomaStr "12345678901234567…12345678901234567890" +
"12345678901234567…12345678901234567890"
Iterações 10.000
tBigN Elapsed 00:00:17
Value 246913578024691357…7802469135780
SomaStr Elapsed 00:00:19
Value 246913578024691357…7802469135780
Diff tBigN x SomaStr 00:00:02

Neste primeiro exemplo executamos as funções 10.000 vezes somando um mesmo valor.

Para o exemplo seguinte, o retorno da soma foi utilizado como reentrada das funções gerando as seguintes informações:

tBigNumber():Add()
Value(1) 246913578024691357…78024691357802469135780
tBigN Elapsed(1) 00:00:00
Value(2) 493827156049382715…56049382715604938271560
tBigN Elapsed(2) 00:00:00
Value(3) 987654312098765431…12098765431209876543120
tBigN Elapsed(3) 00:00:00
Value(4) 197530862419753086…24197530862419753086240
tBigN Elapsed(4) 00:00:00
Value(5) 395061724839506172…48395061724839506172480
tBigN Elapsed(5) 00:00:00
Value(6) 790123449679012344…96790123449679012344960
tBigN Elapsed(6) 00:00:00
Value(7) 158024689935802468…93580246899358024689920
tBigN Elapsed(7) 00:00:00
Value(8) 316049379871604937…87160493798716049379840
tBigN Elapsed(8) 00:00:00
Value(9) 632098759743209875…74320987597432098759680
tBigN Elapsed(9) 00:00:00
Value(10) 126419751948641975…48641975194864197519360
tBigN Elapsed(10) 00:00:00

 

SomaStr()
Value(1) 246913578024691357…78024691357802469135780
SomaStr Elapsed(1) 00:00:00
Value(2) 493827156049382715…56049382715604938271560
SomaStr Elapsed(2) 00:00:00
Value(3) 987654312098765431…12098765431209876543120
SomaStr Elapsed(3) 00:00:00
Value(4) 197530862419753086…24197530862419753086240
SomaStr Elapsed(4) 00:00:00
Value(5) 395061724839506172…48395061724839506172480
SomaStr Elapsed(5) 00:00:00
Value(6) 790123449679012344…96790123449679012344960
SomaStr Elapsed(6) 00:00:00
Value(7) 158024689935802468…93580246899358024689920
SomaStr Elapsed(7) 00:00:00
Value(8) 316049379871604937…87160493798716049379840
SomaStr Elapsed(8) 00:00:00
Value(9) 632098759743209875…74320987597432098759680
SomaStr Elapsed(9) 00:00:00
Value(10) 1126419751948641975…48641975194864197519360
SomaStr Elapsed(10) 00:00:00

 

Iterações 10
tBigN Elapsed 00:00:00
SomaStr Elapsed 00:00:00
Diff tBigN x SomaStr 00:00:00

Para MultStr()

tBigNumber:Mult x MultStr "123456789" x "123456789"
Iterações 1.000
tBigN Elapsed 00:00:01
Value 15241578750190521
MultStr Elapsed 00:00:03
Value 15241578750190521
Diff tBigN x MultStr 00:00:02

Neste primeiro exemplo executamos as funções 1.000 vezes multiplicando um mesmo valor.

Para o exemplo seguinte, o retorno da multiplicação foi utilizado como reentrada das funções gerando as seguintes informações:

 

tBigNumber():Mult()
Value(1) 15241578750190521
tBigN Elapsed(1) 00:00:00
Value(2) 232305722798259244150093798251441
tBigN Elapsed(2) 00:00:00
Value(3) 539659488448216647…5737955899777414752273389058576481
tBigN Elapsed(3) 00:00:00
Value(4) 291232363472190877…6271643076476644758559422126343361
tBigN Elapsed(4) 00:00:00
Value(5) 848162895335982991…4240811378572945803357328868776321
tBigN Elapsed(5) 00:00:00
Value(6) 719380297024717638...7028000621645922491232871930295041
tBigN Elapsed(6) 00:00:00
Value(7) 517508011747370972...3238095453831253600434285309191681
tBigN Elapsed(7) 00:00:00
Value(8) 267814542222717052...5156626985572382913965665599605761
tBigN Elapsed(8) 00:00:01
Value(9) 717246290259634949…1615826154315785539919198624389121
tBigN Elapsed(9) 00:00:03
Value(10) 514442240891208509...7757687748352521290351690423152641
tBigN Elapsed(10) 00:00:11

 

tBigN Elapsed(1) 00:00:00
tBigN Elapsed(2) 00:00:00
tBigN Elapsed(3) 00:00:00
tBigN Elapsed(4) 00:00:00
tBigN Elapsed(5) 00:00:00
tBigN Elapsed(6) 00:00:00
tBigN Elapsed(7) 00:00:00
tBigN Elapsed(8) 00:00:01
tBigN Elapsed(9) 00:00:03
tBigN Elapsed(10) 00:00:11
tBigN Elapsed Total 00:00:15

 

MultStr()
Value(1) 15241578750190521
MultStr Elapsed(1) 00:00:00
Value(2) 232305722798259244150093798251441
MultStr Elapsed(2) 00:00:00
Value(3) 539659488448216647…5737955899777414752273389058576481
MultStr Elapsed(3) 00:00:00
Value(4) 291232363472190877…6271643076476644758559422126343361
MultStr Elapsed(4) 00:00:00
Value(5) 848162895335982991…4240811378572945803357328868776321
MultStr Elapsed(5) 00:00:01
Value(6) 719380297024717638...7028000621645922491232871930295041
MultStr Elapsed(6) 00:00:02
Value(7) 517508011747370972...3238095453831253600434285309191681
MultStr Elapsed(7) 00:00:09
Value(8) 267814542222717052...5156626985572382913965665599605761
MultStr Elapsed(8) 00:00:38
Value(9) 717246290259634949…1615826154315785539919198624389121
MultStr Elapsed(9) 00:02:36
Value(10) 514442240891208509...7757687748352521290351690423152641
MultStr Elapsed(10) 00:10:37

 

MultStr Elapsed(1) 00:00:00
MultStr Elapsed(2) 00:00:00
MultStr Elapsed(3) 00:00:00
MultStr Elapsed(4) 00:00:00
MultStr Elapsed(5) 00:00:01
MultStr Elapsed(6) 00:00:02
MultStr Elapsed(7) 00:00:09
MultStr Elapsed(8) 00:00:38
MultStr Elapsed(9) 00:02:36
MultStr Elapsed(10) 00:10:37
MultStr Elapsed Total 00:14:03

 

Iterações 10
tBigN Elapsed Total 00:00:15
MultStr Elapsed Total 00:14:03
Diff tBigN x MultStr 00:13:48

No caso de MultStr a diferença é GRITANTE. Neste caso a recomendação seria utilizar a função de usuário.

Os Códigos utilizados para este exemplo:

   1: User Function SomaFoo()
   2:     
   3: Local aT1        := Array(10,3)
   4: Local aT2        := Array(10,3)
   5:  
   6: Local cStr        := "123456789012345678901234567890"+;
   7:                    "123456789012345678901234567890"+;
   8:                    "123456789012345678901234567890"+;
   9:                    "123456789012345678901234567890"
  10:  
  11: Local cBNStr    := cStr
  12: Local cMSStr    := cStr
  13:  
  14: Local cBnIni
  15: Local cBnEnd
  16: Local cBnTot
  17: Local cMsIni
  18: Local cMsEnd
  19: Local cMsTot
  20:  
  21: Local i
  22:  
  23: Local oTBN    := tBigNumber():New(cBNStr)
  24:  
  25: ConOut("","tBigNumber:ADD x SomaStr","-------------------------------------------------------","")
  26:  
  27: cBnIni    := Time()
  28: For i := 1 To 10000
  29:     oTBN:Add( oTBN ):ExactValue()
  30: Next i
  31: --i
  32: cBnEnd    := Time()
  33: ConOut("",;
  34:         PadR("tBigN Elapsed",21)+;
  35:         " : "+;
  36:         (cBnTot:=ElapTime(cBnIni,cBnEnd)),;
  37:         PadR("Iteracoes",21)+;
  38:         " : "+;
  39:         LTrim(Str(i)),PadR("Value",21)+;
  40:         " : "+;
  41:         oTBN:Add(oTBN):ExactValue())
  42:  
  43: ConOut("","-------------------------------------------------------","")
  44:  
  45: cMsIni    := Time()
  46: For i := 1 To 10000
  47:     SomaStr( cMsStr , cMsStr )
  48: Next i
  49: --i
  50: cMsEnd    := Time()
  51: ConOut("",;
  52:     PadR("SomaStr Elapsed",21)+;
  53:     " : "+;
  54:     (cMsTot:=ElapTime(cMsIni,cMsEnd)),;
  55:     PadR("Iteracoes",21)+;
  56:     " : "+;
  57:     LTrim(Str(i)),;
  58:     PadR("Value",21)+;
  59:     " : "+;
  60:     SomaStr(cMsStr,cMsStr))
  61:  
  62: ConOut("",;
  63:     PadR("Diff tBigN x SomaStr",21)+;
  64:     " : "+;
  65:     ElapTime(cBnTot,cMsTot),PadR("Iteracoes",21)+;
  66:     " : "+;
  67:     LTrim(Str(i)),"")
  68:  
  69: ConOut("","-------------------------------------------------------","")
  70:  
  71: cBnIni    := Time()
  72: For i := 1 To 10
  73:     aT1[i][1]    := Time()
  74:     ConOut(;
  75:         PadR("Value("+LTrim(Str(i))+")",21)+;
  76:         " : "+;
  77:         oTBN:SetValue(oTBN:Add(oTBN):ExactValue()):ExactValue())
  78:     aT1[i][2]    := Time()    
  79:     ConOut(;
  80:         PadR("tBigN Elapsed("+LTrim(Str(i))+")",21)+;
  81:         " : "+;
  82:         (aT1[i][3]:=ElapTime(aT1[i][1],aT1[i][2])),"")
  83: Next i
  84: --i
  85: ConOut("")
  86: aEval(aT1,{|x,y|ConOut(PadR("tBigN Elapsed("+LTrim(Str(y))+")",21)+" : "+x[3])})
  87: cBnEnd    := aT1[i][2]
  88: ConOut("",;
  89:     PadR("tBigN Elapsed",21)+;
  90:     " : "+;
  91:     (cBnTot:=ElapTime(cBnIni,cBnEnd)),;
  92:     PadR("Iteracoes",21)+;
  93:     " : "+;
  94:     LTrim(Str(i)),"")
  95:  
  96: ConOut("","-------------------------------------------------------","")
  97:  
  98: cMsIni    := Time()
  99: For i := 1 To 10
 100:     aT2[i][1]    := Time()
 101:     ConOut(;
 102:         PadR("Value("+LTrim(Str(i))+")",21)+;
 103:         " : "+;
 104:         (cMsStr:=SomaStr(cMsStr,cMsStr)))
 105:     aT2[i][2]    := Time()
 106:     ConOut(;
 107:         PadR("SomaStr Elapsed("+LTrim(Str(i))+")",21)+;
 108:         " : "+;
 109:         (aT2[i][3]:=ElapTime(aT2[i][1],aT2[i][2])),"")
 110: Next i
 111: --i
 112: ConOut("")
 113: aEval(aT2,{|x,y|ConOut(PadR("SomaStr Elapsed("+LTrim(Str(y))+")",21)+" : "+x[3])})
 114: cMsEnd    := aT2[i][2]
 115: ConOut("",;
 116:     PadR("SomaStr Elapsed",21)+;
 117:     " : "+;
 118:     (cMsTot:=ElapTime(cMsIni,cMsEnd)),PadR("Iteracoes",21)+;
 119:     " : "+;
 120:     LTrim(Str(i)),"")
 121:  
 122: ConOut("",;
 123:     PadR("Diff tBigN x SomaStr",21)+;
 124:     " : "+;
 125:     ElapTime(cBnTot,cMsTot),PadR("Iteracoes",21)+;
 126:     " : "+;
 127:     LTrim(Str(i)),"")
 128:  
 129: ConOut("","-------------------------------------------------------","")
 130:  
 131: Return(NIL)


   1: User Function MultFoo()
   2:     
   3: Local aT1 := Array(10,3)
   4: Local aT2 := Array(10,3)
   5:  
   6: Local cStr := "123456789"
   7:  
   8: Local cBNStr := cStr
   9: Local cMSStr := cStr
  10:  
  11: Local cBnIni
  12: Local cBnEnd
  13: Local cBnTot
  14: Local cMsIni
  15: Local cMsEnd
  16: Local cMsTot
  17:  
  18: Local cConOut
  19:  
  20: Local i
  21:  
  22: Local oTBN    := tBigNumber():New(cBNStr)
  23:  
  24: ConOut("","tBigNumber:Mult x MultStr","-------------------------------------------------------","")
  25:  
  26: cBnIni    := Time()
  27: For i := 1 To 1000
  28:     oTBN:Mult( oTBN ):ExactValue()
  29: Next i
  30: --i
  31: cBnEnd    := Time()
  32: ConOut("",;
  33:             PadR("tBigN Elapsed",21)+;
  34:             " : "+;
  35:             (cBnTot:=ElapTime(cBnIni,cBnEnd)),PadR("Iteracoes",21)+;
  36:             " : "+;
  37:             LTrim(Str(i)),PadR("Value",21)+;
  38:             " : "+oTBN:Mult(oTBN):ExactValue())
  39:  
  40: ConOut("","-------------------------------------------------------","")
  41:  
  42: cMsIni    := Time()
  43: For i := 1 To 1000
  44:     MultStr( cMsStr , cMsStr )
  45: Next i
  46: --i
  47: cMsEnd    := Time()
  48: ConOut("",;
  49:             PadR("MultStr Elapsed",21)+;
  50:             " : "+;
  51:             (cMsTot:=ElapTime(cMsIni,cMsEnd)),;
  52:             PadR("Iteracoes",21)+;
  53:             " : "+LTrim(Str(i)),;
  54:             PadR("Value",21)+;
  55:             " : "+MultStr(cMsStr,cMsStr))
  56:  
  57: ConOut("",;
  58:             PadR("Diff tBigN x MultStr",21)+;
  59:             " : "+;
  60:             ElapTime(cBnTot,cMsTot),PadR("Iteracoes",21)+;
  61:             " : "+;
  62:             LTrim(Str(i)),"")
  63:  
  64: ConOut("","-------------------------------------------------------","")
  65:  
  66: cBnIni    := Time()
  67: For i := 1 To 10
  68:     aT1[i][1]    := Time()
  69:     ConOut(;
  70:         PadR("Value("+LTrim(Str(i))+")",21)+;
  71:         " : "+;
  72:         oTBN:SetValue(oTBN:Mult(oTBN):ExactValue()):ExactValue())
  73:     aT1[i][2]    := Time()    
  74:     ConOut(;
  75:         PadR("tBigN Elapsed("+LTrim(Str(i))+")",21)+;
  76:         " : "+;
  77:         (aT1[i][3]:=ElapTime(aT1[i][1],aT1[i][2])),"")
  78: Next i
  79: --i
  80: ConOut("")
  81: aEval(aT1,{|x,y|ConOut(PadR("tBigN Elapsed("+LTrim(Str(y))+")",21)+" : "+x[3])})
  82: cBnEnd    := aT1[i][2]
  83: ConOut("",;
  84:     PadR("tBigN Elapsed",21)+;
  85:     " : "+;
  86:     (cBnTot:=ElapTime(cBnIni,cBnEnd)),PadR("Iteracoes",21)+;
  87:     " : "+;
  88:     LTrim(Str(i)),"")
  89:  
  90: ConOut("","-------------------------------------------------------","")
  91:  
  92: cMsIni    := Time()
  93: For i := 1 To 10
  94:     aT2[i][1]    := Time()
  95:     ConOut(;
  96:         PadR("Value("+LTrim(Str(i))+")",21)+;
  97:         " : "+;
  98:         (cMsStr:=MultStr(cMsStr,cMsStr)))
  99:     aT2[i][2]    := Time()
 100:     ConOut(;
 101:         PadR("MultStr Elapsed("+LTrim(Str(i))+")",21)+;
 102:         " : "+;
 103:         (aT2[i][3]:=ElapTime(aT2[i][1],aT2[i][2])),"")
 104: Next i
 105: --i
 106: ConOut("")
 107: aEval(aT2,{|x,y|ConOut(PadR("MultStr Elapsed("+LTrim(Str(y))+")",21)+" : "+x[3])})
 108: cMsEnd    := aT2[i][2]
 109: ConOut("",;
 110:     PadR("MultStr Elapsed",21)+;
 111:     " : "+;
 112:     (cMsTot:=ElapTime(cMsIni,cMsEnd)),;
 113:     PadR("Iteracoes",21)+;
 114:     " : "+;
 115:     LTrim(Str(i)),"")
 116:  
 117: ConOut("",;
 118:     PadR("Diff tBigN x MultStr",21)+;
 119:     " : "+;
 120:     ElapTime(cBnTot,cMsTot),PadR("Iteracoes",21)+;
 121:     " : "+;
 122:     LTrim(Str(i)),"")
 123:  
 124: ConOut("","-------------------------------------------------------","")
 125:  
 126: Return(NIL)

 


[]s
иαldσ dj

Comentários

Postagens mais visitadas deste blog

BlackTDN :: RLeg ~ Desvendando a Função ParamBox

Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA

BlackTDN :: Customizando a interface de Login no Protheus e by You

A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã