Bug 2579

Slow string and blob concatenation 23 November, 2020

Frode Guldberg
05 April, 2019
Product: PowerBuilder Category: PowerScript
Version: 2017 R3 Build:
Classification: Publishing: Public
Priority: P3
Status: Verifying Reason:
Frode Guldberg 23 November, 2020
#4
From what you are saying, I guess you have no intention of fixing the problem with string handling in PB? The workaround by using blob-functionality is working, but then I'll suggest you mention this in the helpfiles so that others doesn't run into the same problem. You should say clearly that string concatenation and maybe also other string functions (?) are not recommended for strings larger than x Bytes.
Ken Guo @Appeon 20 November, 2020
#3
Hi Frode,

I would like to check with you if the response provided has been helpful enough
to resolve your case. If so, can we proceed to close the ticket?
Otherwise, do let us know if we can provide you with any further assistance and
keep in mind that you are always welcome to open another ticket in case you
need it.

Regards,
Ken
Ken Guo @Appeon 08 April, 2019
#2
Hi Frode,

As Chris said, this is a known issue in all PB versions. Currently Appeon PB still doesn’t have a plan to optimize this. 
I suggest you use BlobEdit() and BlobMid() functions to work around it when you encounter this issue.

Regards,
Ken
Chris Pollach @Appeon 05 April, 2019
#1
Hi Frode;

   Yes, this has been a known issue with PB even way back into the early Sybase days when the first took over PB from PowerSoft. Since PB2017 was built upon the PB 12.6 code base that SAP gave Appeon - this string handling speed issue has been inherited from that earlier implementation. Appeon has not yet had time to resolve why this has been occurring in *some* implementations. 

  The workaround for this string manipulation performance issue is to use the BlobEdit() and BlobMid() functions instead. You can see an implementation example of that here ...
https://community.appeon.com/index.php/qna/q-a/mutable-string-type-needed-pbni-c-possibility#reply-9331

  In the mean-time, I will pass this ticket on to the main Support/Engineering group to review and their recommendations for a fix.

Regards ... Chris
Frode Guldberg 05 April, 2019
*Phenomenon:
I know it's not a new problem in PB, but I wonder if Appeon has looked into it?
Concatenating strings/blobs are very slow when the string/blob are getting longer. I have made a code example, which fills different kinds of variables, by adding a string value to it in different ways, and timing the jobs. The final messagebox will show that concatenation is waaaay slower than doing a BlobEdit() on an initialized blob. Just for the example I also added the same logics with adding to the end of a blob which is even slower, and putting the strings into a string array which is very fast. The main point tho, is that the string/blob concatenation is very slow. Is there any reason for this or can it be optimalized in PB?

*Reproduce Steps:
String		ls_string, ls_xml_element, ls_temp, ls_string_array[]
Long		ll_counter, ll_total, ll_pos, ll_fileid, ll_start, ll_end
Decimal		ll_diff_1, ll_diff_2, ll_diff_3, ll_diff_4
Blob{18000000}	lblb_blob
Blob		lblb_blob2

SetPointer(HourGlass!)

ll_total = 15000
ls_temp = "This is just a test to see how long it takes to build up a rather large variable. If the variable is a string, it takes a long time to build it.~r~n"

//Logics for a string variable
ll_start = Cpu()

For ll_counter = 1 To ll_total
	ls_string += ls_temp
Next

ll_end = Cpu()
ll_diff_1 = (ll_end - ll_start) / 1000

/*
//Saves the data to a file, just to show the content of the variable
ll_fileid = FileOpen('c:\temp\export_1.txt', TextMode!, Write!)
FileWriteEx(ll_fileid, ls_string)
FileClose(ll_fileid)
*/

//Logics for an instantiated blob variable using BlobEdit()
ll_start = Cpu()
ll_pos = 1

For ll_counter = 1 To ll_total
	ll_pos = BlobEdit(lblb_blob, ll_pos, Blob(ls_temp), EncodingAnsi!)
Next

ll_end = Cpu()
ll_diff_2 = (ll_end - ll_start) / 1000

/*
//Saves the data to a file, just to show the content of the variable
ll_fileid = FileOpen('c:\temp\export_2.txt', StreamMode!, Write!)
FileWriteEx(ll_fileid, lblb_blob)
FileClose(ll_fileid)
*/

//Logics for concatenating to an non-instantiated blob variable
ll_start = Cpu()

For ll_counter = 1 To ll_total
	lblb_blob2 += Blob(ls_temp)
Next

ll_end = Cpu()
ll_diff_3 = (ll_end - ll_start) / 1000

/*
//Saves the data to a file, just to show the content of the variable
ll_fileid = FileOpen('c:\temp\export_3.txt', StreamMode!, Write!)
FileWriteEx(ll_fileid, lblb_blob2)
FileClose(ll_fileid)
*/

//Logics for a string array
ll_start = Cpu()

For ll_counter = 1 To ll_total
	ls_string_array[ll_counter] = ls_temp
Next

ll_end = Cpu()
ll_diff_4 = (ll_end - ll_start) / 1000

MessageBox("Finished", 'String: ' + String(ll_diff_1, '0.###') + ' sek.~r~nBlob 1: ' + String(ll_diff_2, '0.###') + ' sek.~r~nBlob 2: ' + String(ll_diff_3, '0.###') + ' sek.~r~nArray: ' + String(ll_diff_4, '0.###') + ' sek.')


Remarks:
The difference gets bigger and bigger the longer the variables get. Try changing ll_total to 30K or even more.
OS:
Windows 10
Platform:
64-bit
Database Type:
Microsoft SQL Server
Database Version: