Re: About ActiveX performance in Curl
Hi, could you please post a running applet that shows the performance issue? I have tried to assemble something that might be similar to your application. The applet finished within less than have a second. I fills some cells and saves it to test.xls. See attached curl file. Friedger Hello gurus I met a critical performance issue in calling methods/properties of Excel.Application(ActiveXObject) for creating excel files in a Curl applet. This applet is converted from a Visual Basic(6.0) application, so the methods/properties used by the Curl applet is completely the same with the original VB application. With the VB application, creating the xls file costs about twenty seconds, while in Curl, creating the same xls file (containing the same data, the same formatted style) costs about 120 seconds. So, calling methods/properties in Curl applet used about six times long time comparing with the VB application. Attached files are copied from the project codes in VB and Curl accordingly. Note the two applications in VB and Curl are identical in the meaning of function and codes logic. Codes in attached files are called in a for loop of another method/sub. Also note that it has been proved that procs like Variant-to-Boolean, vb-var-diff are not related with this performance issue. Does anyone know any reason about this big difference ? Are there any way to accelerate my Curl applet on outputting excel files with Excel.Application ActiveXObject ? The attached files are encoded in utf-8. Thank you. {curl 6.0 applet} {curl-file-attributes character-encoding = utf8} {import * from CURL.GRAPHICS.ACTIVEX} {define-class ExcelTest field g_xlApp:#ActiveXObject field xlSheetReport: any field w_lngRDLine:int = 1 field w_lngRDLineNo:int = 1 field wb:any {method public {init}:void {set self.g_xlApp = {ActiveXObject ProgId= Excel.Application}} set self.wb = {self.g_xlApp.Workbooks.Add} {set self.xlSheetReport = self.g_xlApp.ActiveSheet} } {method public {psubSheetSet_Detail }:void ||ãã£ãã¼ã«ç·¨é {let with-1:any = self.xlSheetReport} ||NO. ||â».ãç¶ããªãã¯ã {set {with-1.Cells self.w_lngRDLine, 1}.Value = self.w_lngRDLineNo} ||åºé¨èª²ã³ã¼ã ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.TENBUKA_CD, vbNullString}} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 2}.Value = {self.w_typRD.get-value self.w_lngRDCount}.TENBUKA_CD} ||--} ||--||é¨èª²åºæ ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.TENBUKA_RK, vbNullString}} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 3}.Value = {self.w_typRD.get-value self.w_lngRDCount}.TENBUKA_RK} ||--} ||--||å¥ç´å ã³ã¼ã ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.KEIYAKU_CD, vbNullString}} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 4}.Value = {self.w_typRD.get-value self.w_lngRDCount}.KEIYAKU_CD} ||--} ||--||å¥ç´å å ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.KEIYAKU_NM, vbNullString}} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 5}.Value = {self.w_typRD.get-value self.w_lngRDCount}.KEIYAKU_NM} ||--} ||--||åå¼å½¢æ ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.TORIKEI_KBN, vbNullString}} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 6}.Value = {g_objConsTori.Item {self.w_typRD.get-value self.w_lngRDCount}.TORIKEI_KBN}.Value} ||--} ||--||ï¼ï¼¦ ||--{if {Variant-to-Boolean {vb-var-diff {self.w_typRD.get-value self.w_lngRDCount}.MF_KBN, }} then ||--||â».ãç¶ããªãã¯ã ||--{set {with-1.Cells self.w_lngRDLine, 7}.Value = {g_objConsMF.Item {self.w_typRD.get-value self.w_lngRDCount}.MF_KBN}.Value} ||--} ||--||å¥ç´çªå· ||â».ãç¶ããªãã¯ã ||REV ||â».ãç¶ããªãã¯ã {set {with-1.Cells self.w_lngRDLine, 9}.Value = ABC} ||éå§æ¥ ||â».ãç¶ããªãã¯ã {set {with-1.Cells self.w_lngRDLine, 10}.Value = {{proc {}:String let byref-1:{FastArray-of String} = {{FastArray-of String} XYZ} let ret:String = RET {return ret ||ï¼² {if false then else ||--{if {Variant-to-Boolean {vb-var-equal {Trim {self.w_typRD.get-value self.w_lngRDCount}.REMARK}, 1}} then ||--||â».ãç¶ããªãã¯ã ||--
Re: About ActiveX performance in Curl
tian_rose wrote: Hello gurus I met a critical performance issue in calling methods/properties of Excel.Application(ActiveXObject) for creating excel files in a Curl applet. The first thing you should do is to run this using the profiling tool in the Pro IDE. This should tell you were the time is being spent. If you don't find the explanation in your own code, then you should save the profile output using Save As from the File menu of the Profile Viewer and send the file to [EMAIL PROTECTED] so we can take a look at it. - Christopher This applet is converted from a Visual Basic(6.0) application, so the methods/properties used by the Curl applet is completely the same with the original VB application. With the VB application, creating the xls file costs about twenty seconds, while in Curl, creating the same xls file (containing the same data, the same formatted style) costs about 120 seconds. So, calling methods/properties in Curl applet used about six times long time comparing with the VB application. Attached files are copied from the project codes in VB and Curl accordingly. Note the two applications in VB and Curl are identical in the meaning of function and codes logic. Codes in attached files are called in a for loop of another method/sub. Also note that it has been proved that procs like Variant-to-Boolean, vb-var-diff are not related with this performance issue. Does anyone know any reason about this big difference ? Are there any way to accelerate my Curl applet on outputting excel files with Excel.Application ActiveXObject ? The attached files are encoded in utf-8. Thank you.
Re: About ActiveX performance in Curl
Thank you, William! Your explanation makes sense to me. The first paragraph in your reply explained why ActiveXObject calls for Excel in Curl is slower than VB does, and this is the most important information for me. As for the Curl codes itself, there are much things to do for us to make the codes more efficient. Because the VB2Curl converter is written by a Java programmer who is not so familiar with Curl, and also becuase we need to sacrifice some efficiency to simplify the converter itself, the Curl codes generated from this converter need to be tuned, as you pointed out. Your advice will help us greatly. I also confirmed that setting values of each cell by calling Cells property in Excel could be accelerated by saving values into a String and then paste it to a Range using Excel's Paste command by only one time. Thank you very much. Deng --- William Bardwell [EMAIL PROTECTED] wrote: There are some differences in how the Curl RTE does COM calls, Visual Basic uses the COM types and COM methods directly, where the ActiveXObject class uses IDispatch::Invoke. This means that the ActiveXObject class is doing more work converting things to and from VARIANTs as well as the COM code has to look up methods. Also depending on how the ActiveX code in Excel is written, if it returns new IUnknowns each time an object is requested that will slow things down because the Curl RTE ends up needing to re-lookup what methods and properties it has. So, while the Curl language code probably can not be as fast as the VB code, there are several things that you can do to speed up your code. 1) Save intermediate values that are reused, in particular in your sample {self.w_typRD.get-value self.w_lngRDCount} is done lots and lots of times, save that value in a variable and use that variable. Similarly for each field you fetch it once to compare and once to save it, save that in a variable. 2) Use ActiveXObject as the type for any object that is an ActiveXObject. This will avoid the overhead of 'any' calls. (So change: {let with-1:any = self.xlSheetReport} to be let with-1:ActiveXObject = self.xlSheetReport And I suspect although I am not sure that you should be doing: let rd-value:ActiveXObject = {self.w_typRD.get-value self.w_lngRDCount} asa ActiveXObject (assuming that that is an ActiveXObject.) I suspect that this stuff could be optimized, to not be doing those conversions: {Variant-to-Boolean {vb-var-diff ...}} but I am not sure what it is doing, so I am not sure if that is true. If those values are just strings or integers or some such then you can just compare them in the Curl language code. And in any case you could probably skip using Variants some how. This is also strange: {set {with-1.Cells self.w_lngRDLine, 10}.Value = {{proc {}:String let byref-1:{FastArray-of String} = {{FastArray-of String} {self.w_typRD.get-value self.w_lngRDCount}.KAISHI_YMD} let ret:String = {substrDateChange byref-1, {{FastArray-of String} g#e.#m.#d}} {set {self.w_typRD.get-value self.w_lngRDCount}.KAISHI_YMD = byref-1[0]} {return ret You can just use {value} instead of an inline proc. And you can use Pointer-to or Reference-to (if on 6.0) instead of the FastArray-of. But it also looks like you don't need a to do any of that stuff by reference, you can just return two values from {substrDateChange}. And the second argument for substrDateChange doesn't look like it needs to be by reference in any case. So you could have something like: let rd-value:ActiveXObject = {self.w_typRD.get-value self.w_lngRDCount} asa ActiveXObject set {with-1.Cells self.w_lngRDLine, 10}.Value = {value let (ret:String, replacement-ymd:String) = {substrDateChange rd-value.KAISHI_YMD, g#e.#m.#d} set rd-value.KAISHI_YMD = replacement-ymd ret } William Bardwell [EMAIL PROTECTED]