[AccessD] Array faster in DLL?

Shamil Salakhetdinov shamil at users.mns.ru
Mon Oct 31 02:40:17 CST 2005


Hi Gustav,

With switched off array bounds check and integer overflow check your
sample code runs in less than 1 second when in VB6 bActiveX dll.

Similar code in C++(VS.NET 2003) runs instantaneously.

C++ allows to measure time when 10^6 cycles are additionally cycled
10^7 times!

Below is sample C++ code. Maybe I did make some mistakes -
10^7 * 10^6 loops in just two seconds looks incredible speed
gain under C++ - these are 989,999,010,000,000 cycles...

And in 19 seconds 9,899,990,100,000,000 cycles can be executed.

long ArrayTimeLocal(long lngLoopMax, long& lngTotalCnt);
int _tmain(int argc, _TCHAR* argv[])
{
 long dblStart;
 long dblStop;
 long lngResult;
 long lngCnt = 0;
 __int64 totalCnt = 0;
 time(&dblStart);
 for (int i = 1; i<=10000000; i++) {
  lngResult = ArrayTimeLocal(1000000, lngCnt);
  totalCnt += ((__int64)lngCnt);
  if ((i % 1000000) == 0)
   printf("Result = %ld, Counter = %I64d\n",
    lngResult, totalCnt);
 }
    time(&dblStop);
 lngResult = (long)difftime(dblStop,dblStart);
 printf("Final Result = %ld, Final Counter = %I64d\n",
     lngResult, totalCnt);
}

long ArrayTimeLocal(long lngLoopMax, long& lngTotalCnt) {
  const long lngItems = 100;
  long alngTmp[lngItems-1][1];
  long lngLoop;
  long lngItem;
  long lngResult;
  long lngSeconds;
  long dblStart;
  long dblStop;

  lngTotalCnt = 0;
  time(&dblStart);
  for (lngLoop=1; lngLoop < lngLoopMax; lngLoop++) {
   for (lngItem=1; lngItem < lngItems; lngItem++) {
  alngTmp[lngItem-1][0] = lngLoop * 10;
  if (alngTmp[lngItem-1][0] / 10 == 100) lngResult = 1;
  else lngResult = 0;
  lngTotalCnt++;
   }
  }
  time(&dblStop);
  lngSeconds = (long)difftime(dblStop,dblStart);
  return lngSeconds;
}

And here is result of this code test run:

Result = 0, Counter = 98999901000000
Result = 0, Counter = 197999802000000
Result = 0, Counter = 296999703000000
Result = 0, Counter = 395999604000000
Result = 0, Counter = 494999505000000
Result = 0, Counter = 593999406000000
Result = 0, Counter = 692999307000000
Result = 0, Counter = 791999208000000
Result = 0, Counter = 890999109000000
Result = 0, Counter = 989999010000000
Final Result = 2, Final Counter = 989999010000000

Shamil

----- Original Message ----- 
From: "Gustav Brock" <Gustav at cactus.dk>
To: <accessd at databaseadvisors.com>
Sent: Sunday, October 30, 2005 11:16 PM
Subject: Re: [AccessD] Array faster in DLL?


> Hi Marty, Shamil, Fred et all
>
> Well, I did a small and quite surprising test inspired by Shamil.
> Here is a test routine which can be seen as typical for what I do.
> The array is not large but it is read from and written to a bunch of
times.
>
> Here is the local test using standard VBA:
>
> Function ArrayTimeLocal(ByVal lngLoopMax As Long) As Long
>
>   Const lngItems                      As Long = 100
>
>   Dim alngTmp(1 To lngItems, 1 To 2)  As Long
>   Dim lngLoop                         As Long
>   Dim lngItem                         As Long
>   Dim lngResult                       As Long
>   Dim lngSeconds                      As Long
>   Dim dblStart                        As Double
>   Dim dblStop                         As Double
>
>   dblStart = Timer
>
>   For lngLoop = 1 To lngLoopMax
>     For lngItem = 1 To lngItems
>       alngTmp(lngItem, 1) = lngLoop * 10
>       If alngTmp(lngItem, 1) / 10 = 100 Then
>         lngResult = 1
>       Else
>         lngResult = 0
>       End If
>     Next
>   Next
>
>   dblStop = Timer
>   lngSeconds = CLng(dblStop - dblStart)
>
>   ArrayTimeLocal = lngSeconds
>
> End Function
>
> And this is the test function using an DLL containing nearly identical
code:
>
> Declare Function ArrayTime Lib "arraydll.dll" Alias "ArrayTime at 4" (ByVal
lngLoops As Long) As Long
>
> Function ArrayTimeDLL(ByVal lngLoopMax As Long) As Long
>
>   ArrayTimeDLL = ArrayTime(lngLoopMax)
>
> End Function
>
> The DLL was programmed and compiled in FreeBASIC and the FBIde which I
earlier posted links for.
>
> Setting lngLoopMax to 10^6 returns these running times for the two
functions:
>
>   ArrayTimeLocal: 34 seconds
>   ArrayTimeDLL: 2.2 seconds (measured with 10^7 loops)
>
> Thus this simple tool gives a speed improvement of 15.5 to 1 ... not bad!
>
> Nothing comes free, and the trouble is - as far as I can see - that the
dll has to be programmed to run rock stable. If it errors out, Access halts
or simply quits - no errors, no GPF, just poof away.
>
> With this result I think I'll leave the assembler stuff for now. Still, if
anyone with PowerBasic or other compiler could make similar tests and
publish the results, we could rank these.
>
> /gustav
>
>
> >>> martyconnelly at shaw.ca 30-10-2005 20:08 >>>
> Personally if I am using arrays or a lot of matrix math like Fourier
Transforms. I develop in Intel Fortran Compiler for Windows & Visual Fortran
but I can write Fortran in my sleep.
> It is COM compliant and callable from VBA. I have written DOS assembler a
long time ago what I could do in a day in Fortran would take me 6 weeks in
assembler just because I would have to relearn so much. Microsoft VB with
arrays has a lot of overhead of error, type and range checking.
> Come to think of it IBM Fortran compilers and maybe others used to produce
an optional ASM listing that might help you out.
>
> MartyConnelly wrote:
>
> >If you are working with really for sure definetely absolutely fixed size
> >arrays in VB6 dll you can
> >turn off Remove Array Bounds Checks option for about 25% speed
> >performance increase.
> >With the chance of a GPF
>
>
> -- 
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com




More information about the AccessD mailing list