1. Fernando Leal
  2. PowerBuilder
  3. Sunday, 15 November 2020 13:31 PM UTC

Hi People, 

How can I Optimize FOR statement in PB2019?
I have noticed that these loops produce a 90 second delay.

 

nteger row, col, colByte, col2, k, l, i
long cols
byte lb_char
int Rows
Rows = lngHeight
cols =ll_ancho_col //lngWidth -comentado agregar ancho columna entero

k = 0
For row = 0 To Rows - 1
For colByte = 0 To lngRowSize - 1

lb_char = ly_byte[((row * lngRowSize) + colByte + 1)+ lngOffset ]
For i = 7 To 0 Step -1

col = (colByte * 8) + i
If col < Cols Then
//pict.Dot(row + 1, col + 1) = MOD(lb_char,2)
lb_Array[row + 1, col + 1] = MOD(lb_char,2)

End If

lb_char = byte(truncate(int(lb_char) / 2,0))//Fix(lb_char / 2)
Next //i


Next //colByte
k = k + 1
Next //row


//
//Dim strHeader
// Dim strImage
//
byte lb_char2
string strImage =""
string strHeader

string C_FL = char(13) + char(10)
li_col_x_col = li_columna
//comentado para prueba
k = 0
string ls_concatenar
int li_valid_col = 1
For row = Rows To 1 Step -1
For col = 1 To Cols
//i = pict.Dot(row, col)
i = lb_Array[row,col]
lb_char2 = lb_char2 + (i * (2 ^ (3 - k)))
k = k + 1
ls_concatenar = ls_concatenar + string(i)
If k = 4 Then
lb_char2 = 15 - lb_char2
if lb_char2 <= 9 then
strImage = strImage + string(lb_char2)
else
choose case lb_char2
case 10
strImage = strImage + "A"
case 11
strImage = strImage + "B"
case 12
strImage = strImage + "C"
case 13
strImage = strImage + "D"
case 14
strImage = strImage + "E"
case 15
strImage = strImage + "F"

end choose

end if
k = 0
lb_char2 = 0
End If
// //primera línea ponerle el salto de carro ya que sobrepasa la matriz definida
if len(strImage) = li_columna then
strImage = strImage + C_FL
//continue;
end if

Next //col

If row <> Rows Then
strImage = strImage + C_FL
End If
Next //row

//Cerramos el archivo
FileClose(li_File)

 

thanks and regards,

 

Fernando.

 

Accepted Answer
Michael Kramer Accepted Answer Pending Moderation
  1. Monday, 16 November 2020 20:18 PM UTC
  2. PowerBuilder
  3. # Permalink

Hi Fernando,

There is nothing wrong with PowerScript's FOR-loop itself.

My bet is most of the execution time is spent in string concatenation. As I read your code it is building a potentially long, long text string one character at a time. Each character appended means new string allocation + copy of existing string. Just construction of such a string has complexity order = O(n²).

As Miguel points out, Roland Smith has excellent string builder class, free for use. It is conceptually similar to StringBuilder classes you find in other languages. Its internal buffer is a BLOB which is extended in large chunks. An internal pointer tells the code where to write the next characters.

Also, after reading your code a couple of times more, it looks like it uses multiplication, division, and power-of to convert some dataset into hexadecimal values. There are faster ways to do that.

Example for inspiration - - convert a byte value into a hexadecimal value:

FUNCTION string GetHexadecimal(byte b)
   // Returns value of B represented as hexadecimal value
   char c[0 to 15] = "0123456789ABCDEF"
   return c[b / 16] + c[Mod(b, 16)]
END FUNCTION

 

You may opt to concatenate in opposite order.

HTH /Michael

Comment
  1. Fernando Leal
  2. Monday, 16 November 2020 20:25 PM UTC
Hi Michael, very good comments,

thanks and regards,



Fernando.

  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Sunday, 15 November 2020 19:10 PM UTC
  2. PowerBuilder
  3. # 1

Greetings, Fernando -

If you are asking for suggestions on a more efficient algorithm, perhaps you could please explain what the code sample you provided does?

I see a two-dimensional array of unknown data type (byte?) and extremely few comments, so it is very difficult to advise you. It appears you are converting a potentially large quantity of binary data into a string representation of hexadecimal. Is this correct? What is the size of the two-dimensional array? What is the source of the (binary?) data? What will be done with the converted data? I see a FileClose, but no FileOpen, read or write operations.

This code performs a LOT of string concatenations, which are slow and inefficient, particularly as the length of the string grows to be large. Given the speed of today's CPUs, I'm guessing the size of the array is substantial if this code takes 90 seconds to execute.

Regards, John

Comment
  1. Miguel Leeuwe
  2. Monday, 16 November 2020 00:04 AM UTC
I agree with John, most probably the string operations are what's slowing down the most. You can use this code made available by Roland Smith to speed up your string operations: https://topwizprogramming.com/freecode_stringclass.html.



Also, the calculations done might be faster when done in other languages like using a C++ or C# DLL.

I once read somewhere that Integer variables, internally are converted to longs before being used by the compiler in powerbuilder (keeping the limitations of integer though), so maybe you could get a very minimal improvement by declaring all of the integers directly as long types. I've never done any test on how much that might improve in execution time.

Saludos
  1. Helpful
  1. Fernando Leal
  2. Monday, 16 November 2020 20:27 PM UTC
Hi John\ Miguel,

The purpose of this query is to be able to eliminate the FOR statement and not consume CPU cycles.

Thank you very much for your time and help.



Fernando.
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.