[progress Communities] [progress Openedge Abl] Forum Post: Performance Overhead When Using...

  • Thread starter Thread starter dbeavon
  • Start date Start date
Status
Not open for further replies.
D

dbeavon

Guest
I was playing with a slow appserver routine today (in ABL) and noticed a number of performance issues. While tweaking the code, I was able to make an impact on the overall duration of a round-trip to state-free appserver. We had a loop of about *** 3000 records *** that were being returned to the client (from a database buffer into a dataset and out). The best case scenario was able to fetch them in about 100 ms. And, depending on how I changed the organization of the code, it went up to about 450-500 ms. Firstly, the dataset records were initially populated from the database buffer using about 60 "assign" statements (one per field coming out of the database buffer). In comparison, the breaking down of these assignments into just 5 assign statements (times the 3000 records) saved a little over 50 ms. Yes, that is still a thing. Another thing I was doing was capturing the MD5 hash of the entire raw buffer for optimistic locking (concurrency) purposes. I figured that if I had the buffer in memory anyway, it would be appropriate to do a quick hash of it, for the off-chance someone may want to edit it. I used code like the following. RAW-TRANSFER BUFFER PB_ {4} TO FIELD v_OldRawMd5. v_OldRawMd5 = MD5-DIGEST (v_OldRawMd5). RETURN v_OldRawMd5. Turns out that this added a little over 50 ms for the hash, and 50 ms because did the work in a separate, private method. One of the biggest shockers was the overhead for organizing code into separate methods. Calling the following from my (3000 record) loop seems to add about 50 ms, with nothing happening in it at all: METHOD PRIVATE VOID GetExtraDataForRecordCreation ( BUFFER PBgen_loc FOR gen_loc , INPUT-OUTPUT p_CoMingStatus AS CHARACTER , INPUT-OUTPUT p_MasterLocation AS CHARACTER , INPUT-OUTPUT p_LocationStatus AS CHARACTER , INPUT-OUTPUT p_Percent AS DECIMAL , INPUT-OUTPUT p_ULCost AS DECIMAL , INPUT-OUTPUT p_ULUnit AS CHARACTER ): /* nothing */ END METHOD . I did all my tests with compiled code, and all 4GLTRACE logging turned off . I did use the abbreviated AS trace logging to capture the duration of my state-free appserver requests (retrieving 3000 records). I don't know if my math adds up properly but I hope you see the general idea. The loop thru the 3000 database records used 3 private method calls in each iteration, 60 assign statements, and captured an MD5 hash, it also passed around the output dataset as an INPUT-OUTPUT parameter to the private methods BY-REFERENCE. The code was really well organized and easy to read in the form that takes 450-500 ms. It becomes worse and worse as we approach 100 ms. It seems that ABL requires us to make some pretty ugly compromises for the sake of performance. I wish the overhead of calling private methods wasn't so large. Or maybe Progress should consider enhancing its compiler to automatically inline the code of a private method, if conditions in the caller will allow. Anyway, I probably spent too much time at this, and I imagine many others have done similar tests. Is there any recent documentation with "dos" and "don'ts" for performance in ABL? I'd especially like to know about when private methods should be avoided and what the exact reasons are for the overhead (ie. is it certain types of parameters, by data type, INPUT/OUTPUT type, do BY-REFERENCE datasets have performance overhead, etc).

Continue reading...
 
Status
Not open for further replies.
Back
Top