# Thread: [RESOLVED] Make this faster

1. ## [RESOLVED] Make this faster

My friend and I are comparing VB's speed to C++, and so far his is a lot faster (about 10 x's).

Maybe some speed guru could help make this even faster using some APIs I probably don't know about or other techniques? It's basically math.

Anyway, here's my code, followed by his C++ code.

Code:
```Option Explicit

Private Const MILLION As Long = 1000001

Private Type Vector
x As Long
y As Long
z As Long
End Type

Private Type LARGE_INTEGER
LowPart As Long
HighPart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private udtStart As LARGE_INTEGER, udtEnd As LARGE_INTEGER
Private curStart As Currency, curEnd As Currency
Private udtFrequency As LARGE_INTEGER, curFrequency As Currency

Private Sub Vector_Add(ByRef TheVector As Vector, ByVal Factor As Long)

With TheVector
.x = .x + Factor
.y = .y + Factor
.z = .z + Factor
End With

End Sub

Private Sub Vector_Multiply(ByRef TheVector As Vector, ByVal Factor As Long)

With TheVector
.x = .x * Factor
.y = .y * Factor
.z = .z * Factor
End With

End Sub

Private Sub Vector_Divide(ByRef TheVector As Vector, ByVal Factor As Long)

With TheVector
.x = .x / Factor
.y = .y / Factor
.z = .z / Factor
End With

End Sub

Private Function LargeIntToCurrency(ByRef LargeInteger As LARGE_INTEGER) As Currency

CopyMemory LargeIntToCurrency, LargeInteger, LenB(LargeInteger)
LargeIntToCurrency = LargeIntToCurrency * 10000

End Function

If QueryPerformanceFrequency(udtFrequency) = 0 Then
MsgBox "QPC not available on your piece of **** computer!", vbExclamation
End If

curFrequency = LargeIntToCurrency(udtFrequency)

Dim v1 As Vector, v2 As Vector, v3 As Vector

With v1
.x = 1
.y = 2
.z = 3
End With

With v2
.x = 100
.y = 200
.z = 300
End With

With v3
.x = 40
.y = 50
.z = 60
End With

Dim tmp1 As Vector, tmp2 As Vector
Dim tmp3 As Vector, tmp As Vector

tmp = v1
'tmp += 1

If tmp.x = 2 And tmp.y = 3 And tmp.z = 4 Then
MsgBox "Test1: Ok!", vbInformation
End If

tmp = v2
'tmp *= 2
Vector_Multiply tmp, 2

If tmp.x = 200 And tmp.y = 400 And tmp.z = 600 Then
MsgBox "Test2: Ok!", vbInformation
End If

tmp = v3
Vector_Divide tmp, 10

If tmp.x = 4 And tmp.y = 5 And tmp.z = 6 Then
MsgBox "Test3: Ok!", vbInformation
End If

'* Timed code begins here *
'TIME_BEGIN:
QueryPerformanceCounter udtStart

Dim i As Long

For i = 1 To MILLION

'Vector 1
'CopyMemory tmp, v1, 12
tmp = v1

With tmp
.x = .x + i
.y = .y + i
.z = .z + i

.x = .x * i
.y = .y * i
.z = .z * i

.x = .x / i
.y = .y / i
.z = .z / i
End With

'Vector 2
'CopyMemory tmp, v2, 12
tmp = v2

With tmp
.x = .x + i
.y = .y + i
.z = .z + i

.x = .x * i
.y = .y * i
.z = .z * i

.x = .x / i
.y = .y / i
.z = .z / i
End With

'Vector 3
'CopyMemory tmp, v3, 12
tmp = v3

With tmp
.x = .x + i
.y = .y + i
.z = .z + i

.x = .x * i
.y = .y * i
.z = .z * i

.x = .x / i
.y = .y / i
.z = .z / i
End With

Next i

'TIME_END:
QueryPerformanceCounter udtEnd

curStart = LargeIntToCurrency(udtStart)
curEnd = LargeIntToCurrency(udtEnd)

'((end - start) / freq) * 1000)
MsgBox ((curEnd - curStart) / curFrequency) * 1000, vbInformation

End Sub```

C++ code:
Code:
```#include <stdio.h>
#include <windows.h>

#pragma comment(lib, "kernel32")

#define TIME_BEGIN double freq, start, end;                           \
QueryPerformanceFrequency((LARGE_INTEGER *)&freq); \
QueryPerformanceCounter((LARGE_INTEGER *)&start);

#define TIME_END    QueryPerformanceCounter((LARGE_INTEGER *)&end);   \
printf("Timer: &#37;f ms\n", ((end - start) / freq) * 1000);

struct vector
{
double x, y, z;

void operator += (long f)
{
x += f;
y += f;
z += f;
}
void operator *= (long f)
{
x *= f;
y *= f;
z *= f;
}
void operator /= (long d)
{
x /= d;
y /= d;
z /= d;
}
};

#define MILLION 1000000

vector v1 = { 1.0,   2.0,   3.0   };
vector v2 = { 100.0, 200.0, 300.0 };
vector v3 = { 40.0,  50.0,  60.0  };
vector tmp1;
vector tmp2;
vector tmp3;
vector tmp;

int main()
{
tmp = v1;
tmp += 1;
if (tmp.x == 2.0 && tmp.y == 3.0 && tmp.z == 4.0)
printf("test1: Ok!\n");

tmp = v2;
tmp *= 2;
if (tmp.x == 200.0 && tmp.y == 400.0 && tmp.z == 600.0)
printf("test2: Ok!\n");

tmp = v3;
tmp /= 10;
if (tmp.x == 4.0 && tmp.y == 5.0 && tmp.z == 6.0)
printf("test3: Ok!\n");

TIME_BEGIN;
for (long i = 0; i < MILLION; ++i)
{
tmp1 = v1;
tmp1 += i;
tmp1 *= i;
tmp1 /= i;

tmp2 = v2;
tmp2 += i;
tmp2 *= i;
tmp2 /= i;

tmp3 = v3;
tmp3 += i;
tmp3 *= i;
tmp3 /= i;
}
TIME_END;
while (true);
return 0;
}```
Edit: His code only takes about 5ms compared to mine, which takes about 500ms.

2. ## Re: Make this faster

Doesn't surprise me. Number crunching is what C/C++ does best. One of the reasons is that C/C++ will compile to native code, while VB, especially VB6 runs through an interpreter engine as it is running.

You can try changing the compile otions to compile to NAtive code, see if the EXE runs any faster that way.

There's a reason a lot of games and graphics intense applications are written in C/C++ and not VB.

-tg

4. ## Re: Make this faster

Not everything goes through the VB runtime, a lot gets compiled to true machine code.

I had more faith in VB than I should have, I guess. With well-written code it seems to perform really well. Maybe just not at math.

Anyway, we changed it to use Long instead of floating point, so if anyone has any ideas to make it faster, please post.

I updated original post with new code.

5. ## Re: Make this faster

Sorry.. .that's not to say there isn't something that could be done... I've just never needed that level of speed like that, so I wouldn't know if there is something that could be done.

-tg

6. ## Re: Make this faster

Doing this kind of speed comparison is on almost the pointless side. One thing that should be accounted for is that C++ compilers generally optimize a whole lot. This means they may remove code and actually not do what has been written. This in turn means that people who don't know this start thinking C++ would somehow be more awesome than it really is (at times). VB's compiler does optimization too, but being based on a very old C compiler it doesn't have that many tricks in it's sleeve. In this case I think the C++ compiler may very well just execute the very last iteration of the loop, because the variables are never used for anything else so an intelligent compiler could very well do that.

Speedwise, I think one of the issues is that you're using a Type. Also, the trust you have an API goes into vain: making a single API call costs a lot more processing power than you'd think, because VB does things such as tracking API errors automatically in the background, which means calling CopyMemory in VB6 takes far more time than it does in C++. The actual memory copy happens just as quickly, it is just all the other things that make things go slower than one would expect.

A better comparison could be done with something that actually does something worthwhile and prevents C++ compiler to do code removing optimizations. Like, parse some kind of file data. However, an optimized C++ will still be likely to be faster, because VB6 doesn't provide stuff such as bitshifting, so you're forced to use slower methods to get the same results.

Edit!
You can just remove LARGE_INTEGER and replace it with Currency. No need to make a conversion function.

7. ## Re: Make this faster

Originally Posted by Merri
Doing this kind of speed comparison is on almost the pointless side. One thing that should be accounted for is that C++ compilers generally optimize a whole lot. This means they may remove code and actually not do what has been written. This in turn means that people who don't know this start thinking C++ would somehow be more awesome than it really is (at times). VB's compiler does optimization too, but being based on a very old C compiler it doesn't have that many tricks in it's sleeve. In this case I think the C++ compiler may very well just execute the very last iteration of the loop, because the variables are never used for anything else so an intelligent compiler could very well do that.

Speedwise, I think one of the issues is that you're using a Type. Also, the trust you have an API goes into vain: making a single API call costs a lot more processing power than you'd think, because VB does things such as tracking API errors automatically in the background, which means calling CopyMemory in VB6 takes far more time than it does in C++. The actual memory copy happens just as quickly, it is just all the other things that make things go slower than one would expect.

A better comparison could be done with something that actually does something worthwhile and prevents C++ compiler to do code removing optimizations. Like, parse some kind of file data. However, an optimized C++ will still be likely to be faster, because VB6 doesn't provide stuff such as bitshifting, so you're forced to use slower methods to get the same results.

Edit!
You can just remove LARGE_INTEGER and replace it with Currency. No need to make a conversion function.
Those were my thoughts exactly. I even told him we should do something like file parsing and execution times would be much closer to each other.

At first, he noticed that the compiler actually removed most of the code, but then he changed it so that it didn't (as far as I know anyway).

I also ended up removing the CopyMemory call later on.

8. ## Re: [RESOLVED] Make this faster

You can use DLL/OCX ... Make the stuff that need Speek on C++ DLL, ans use it with vb ...

9. ## Re: [RESOLVED] Make this faster

Make the stuff that need Speed (not speek sorry) xD

10. ## Re: [RESOLVED] Make this faster

//edit: I'm sorry for digging this out, was searching for something and stumbled over it. Didn't check the date

You could do an Integer division instead of a floating point one and, if allowed, "inline" the type copy:

Code:
```        With tmp
.x = v1.x * i
.y = v1.y * i
.z = v1.z * i

.x = .x \ i
.y = .y \ i
.z = .z \ i

.x = .x + i
.y = .y + i
.z = .z + i
End With
.
.
.```
This runs a lot faster, it takes about 150 ms on my old laptop instead of 700 ms. But it's still slow, compared to the C code, which takes 25 ms with speed optimizations (350 ms without).
Maybe this is because of missing operators like +=, -=, and so on.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

Featured