Re: About ActiveX performance in Curl

2008-03-10 Thread Friedger Müffke

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}
||--}
||--||MF
||--{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

2008-03-10 Thread Christopher Barber

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

2008-03-10 Thread tian_rose

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]