Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring

_Créditos das imagens: ChatGPT_ ### LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring Resolver o problema do [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/description/) é um exercício clássico de programação, que desafia desenvolvedores a encontrar a maior substring palindrômica dentro de uma string. Recentemente, exploramos soluções tanto em Harbour quanto em TLPP (Total Language Protheus Programming). Neste artigo, comparamos as implementações nessas duas linguagens, destacando suas semelhanças, diferenças e funcionalidades específicas. #### Implementações em Harbour ##### Versão 5.1 Essa solução utiliza a técnica de expansão a partir do centro do palíndromo. Cada caractere ou par de caracteres consecutivos é considerado um possível "centro". O algoritmo expande em ambas as direções enquanto os caracteres forem iguais, retornando o maior palíndromo encontrado. ##### Versão 5....

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