[Progress Communities] [Progress OpenEdge ABL] Forum Post: RE: Using Progress.Data.BindingSource for non-GUI Purposes (on Windows)

Status
Not open for further replies.
D

dbeavon

Guest
>>This could not possibly be done in a single round-trip to the CLR bridge From the perspective of a developer using the bridge, it appears like everything is being done in a single round-trip. For example I am calling this method below to receive all the data. It fills a table with three columns: a customer code, name, and number. When execution of the method is complete, my ABL TT is filled with all the data that I need. public static void ReceiveAllData(BindingSource p_Source) { var BindingSourceObj = p_Source; BindingSourceObj.AutoUpdate = true; var Test = BindingSourceObj.GetItemProperties(null); var CodeProp = Test[0]; var NameProp = Test[1]; var NumberProp = Test[2]; for (int i = 0; i < 10000; i++) { var RowNew = BindingSourceObj.AddNew(); CodeProp.SetValue(RowNew, "Code" + i.ToString()); NameProp.SetValue(RowNew, "Cust Name " + i.ToString()); NumberProp.SetValue(RowNew, i); BindingSourceObj.EndEdit(); } } I think you are pointing out that (internally) the implementation is making lots of round-trips between the CLR and AVM. I can see that this is happening to a certain extent, but only by setting breakpoints, and watching the CPU performance in VS diagnostic tools. Quite a lot of work is done managing the capacity of an ArrayList member named "h" (thanks for the obfuscated code, btw. ;-) The ABL side of things was fairly easy to understand. I liked everything about this approach, aside from the performance: USING ClassLibrary1.* FROM ASSEMBLY. DEFINE TEMP-TABLE ttCustomer NO-UNDO FIELD CustomerCode AS CHARACTER FIELD CustomerName AS CHARACTER FIELD CustomerNumber AS INTEGER. DEFINE DATASET dsCustOrder FOR ttCustomer. /* ************************************************************************ */ /* Params and vars */ /* ************************************************************************ */ DEFINE input-OUTPUT PARAMETER DATASET FOR dsCustOrder. DEFINE VARIABLE hTopQuery AS HANDLE NO-UNDO. DEFINE VARIABLE hDataSet AS HANDLE NO-UNDO. DEFINE VARIABLE hTT AS HANDLE NO-UNDO. hDataSet = DATASET dsCustOrder:HANDLE. hTopQuery = hDataSet:TOP-NAV-QUERY(). /* navigation query for customer */ hTopQuery:QUERY-PREPARE("PRESELECT EACH ttCustomer"). hTopQuery:QUERY-OPEN. hTT = BUFFER ttCustomer:HANDLE. /* ************************************************************************ */ /* Prepare binding source */ /* ************************************************************************ */ DEFINE VARIABLE rBindS AS Progress.Data.BindingSource NO-UNDO. rBindS = NEW Progress.Data.BindingSource(hDataSet, hTT). /* ************************************************************************ */ /* Receive */ /* ************************************************************************ */ Class1:ReceiveAllData(rBindS). Hopefully the code is more or less correct. But please let me know if the code is overkill for populating three columns of data in a temp-table. The performance was not great, and I was a bit disappointed since .Net was in the driver's seat and I expected things would be faster. I guess I can see why this approach is not highly recommended for moving large amounts of data from .Net back into ABL. The probindingsource was not designed with this purpose in mind. For one thing, the loop to create new rows in the bindingsource became substantially slower as the number of records increased (it wasn't linear for some reason). Creating 10,000 records takes 800 ms. 20,000 takes 2,700 ms. And 100,000 takes ~50,000 ms. Perhaps this has to do with the unusual way that the ArrayList was constantly changing its capacity. Or maybe it is more complex than that. In any case, I plan to revisit the EXPORT/IMPORT strategy. I will look into the creation of the “EXPORT” format from .Net code. I suspect that the "EXPORT" format is not hard to work with, unless it needs to deal with exceptional data (multi-line, clobs, quotations, delimiters in the data, etc). If anyone can point me to some .Net code (or java?) that already behaves the same as the EXPORT statement, please let me know. I'm wondering if an EXPORT operation ever happens from the PCT code? Once I have EXPORT/IMPORT working then it should perform much better than all the other options I’ve considered so far. I still think it is a bit unfortunate that we would need to write data out to disk and then read it back into memory again (within the same process). But even if the data takes a detour, I expect it to be faster than the "GUI for .Net" bindingsource (and faster than XML or JSON).

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