Re: argh! count number of full stops??
VB Code:
Public Function Sisic4(pStr As Long, pFind As Long, lenStr As Long, lenFind As Long) As Long
Dim i As Long
Dim j As Long
Dim Flag As Long
CopyMemory BufStr(0), ByVal pStr, lenStr
CopyMemory BufFind(0), ByVal pFind, lenFind
i = lenStr - 1
If lenFind = 2 Then
Do Until i < lenFind
If BufStr(i - 1) = BufFind(0) Then
Sisic4 = Sisic4 + 1
End If
i = i - 2
Loop
Else
Do Until i < lenFind
Flag = 0
j = lenFind - 1
Do Until j < 0
If Not (BufStr(i - (lenFind - j)) = BufFind(j - 1)) Then
Flag = -1
Exit Do
End If
j = j - 2
Loop
If Flag = 0 Then
Sisic4 = Sisic4 + 1
End If
i = i - 2
Loop
End If
End Function
Removing the for/loops makes it go faster!!
Sisic3=469, Sisic4=438
Re: argh! count number of full stops??
It's more efficient to pass Long values ByVal instead of ByRef because ByRef results in an indirection whereas ByVal doesn't. Seeing as a pointer is the same size as a Long anyway, you lose instead of gaining. I deleted the benchmarking code so see if that gives any increase in times.
Re: argh! count number of full stops??
No! It makes it slower
Sisic3=475
Sisic4=544
Re: argh! count number of full stops??
Did you put the code in the form. I just realised it has to do a vtable lookup every time it calls the function, so I put it in a module and it is much faster... in fact your Sisic3 function is faster than Sisic4 that you posted in #41.
Re: argh! count number of full stops??
ByVal is faster... told you :D
InStrCount3: 375 ms
Sisic3: 344 ms
Sisic4 with ByRef: 343 ms
Sisic4 with ByVal: 313 ms
Re: argh! count number of full stops??
Yeah I put the function in the form :blush:
Re: argh! count number of full stops??
I managed to get mine to the same speed as yours, they are now basically exactly the same code :D
It is indeed faster to pass the string length as a parameter, and to use module-level buffers instead of statics.
So far I can't really think of any other optimisations to do.
Re: argh! count number of full stops??
I was surprised by the minor increase in speed from dumping the for/loops.
Re: argh! count number of full stops??
Quote:
Originally Posted by penagate
I managed to get mine to the same speed as yours, they are now basically exactly the same code :D
It is indeed faster to pass the string length as a parameter, and to use module-level buffers instead of statics.
So far I can't really think of any other optimisations to do.
I quite often allocate myself 2k of heap at app startup, and then just use that as a workspace. The main problem is, of course, dereferencing. CopyMemory is fine, but for dereferencing it's pretty slow .. .
Re: argh! count number of full stops??
I toyed with the idea of using HeapAlloc, but then the thought of calling CopyMemory on every loop iteration through the string just put me right off.
Re: argh! count number of full stops??
I tried it and it was slower.
Any ideas why for/loops are slower than do/loops. I have been under the impression that for/loops were faster.
Can't remember where I got that idea, from!
Re: argh! count number of full stops??
Neither can I, but I dunno why yours got faster. I tried it too and it over several runs it made no (noticable) difference either way.
BTW, I take that back about not thinking of any other optimisations to do :D
VB Code:
Function InStrCount4( _
ByVal pszString As Long, _
ByVal pszFind As Long, _
ByVal pchSearchChar As Byte, _
ByVal lStringLen As Long, _
ByVal lFindLen As Long _
) As Long
Dim i As Long
Dim j As Long
CopyMemory mchBuf(0), ByVal pszString, lStringLen
If (lFindLen = 2) Then
If (pchSearchChar = 0) Then _
CopyMemory pchSearchChar, ByVal pszFind, 1
Do
If (mchBuf(i) = pchSearchChar) Then _
InStrCount4 = InStrCount4 + 1
i = i + 2
Loop Until i = lStringLen
Else
CopyMemory mchFind(0), ByVal pszFind, lFindLen
Do
Do
If (mchBuf(i + j) <> mchFind(j)) Then
Exit Do
Else
If (j = lFindLen) Then _
InStrCount4 = InStrCount4 + 1
End If
j = j + 2
Loop Until j = lFindLen
i = i + lFindLen
Loop Until i = lStringLen
End If
End Function
Results:
Sisic3: 328 ms
Sisc4 (ByVal): 312 ms
InStrCount4: 282 ms
:D :D
Re: argh! count number of full stops??
Yeah that's pretty fast. Haven't had time to look at it properly (and probably won't) What have you done? (I haven't got your intermediate code!)
Re: argh! count number of full stops??
Got rid of Statics, passed string lengths as parameters, that made it as fast as yours.
Added a choice between passing a pointer to find string buffer, and passing a byte character directly, that made it faster than yours.
Re: argh! count number of full stops??
Oh yeah. That's pretty cool.
If the CopyMemory is typelib defined - then that will make it faster, too (I believe - I haven't tried it yet - but might do some point this week)
Re: argh! count number of full stops??
according to MSDN Help using ordinal numbers is supposed to be faster than function names. However, I tried, and it made no difference whatsoever. You'd think it would be handled the same way by the linker anyway, so I fail to see the logic behind that one.
Re: argh! count number of full stops??
VB Code:
[
uuid(842b47f0-0b27-11da-8cd6-0800200c9a66),
version(0.1),
helpstring("Win32 API Kernel32.DLL")
]
library Win32Stuff
{
importlib("stdole2.tlb");
[dllname("kernel32")]
module kernel32
{
[
entry("RtlMoveMemory")
]
VOID CopyMemory ([in,out] LONG* lpDestination, [in,out] LONG* lpSource, [in] LONG Length);
}
}
Compile this using MkTypLib (you may need to set a few path environment variables) remove 'CopyMemory' from your declare list and reference the compiled type library.
I get around 18% performance boost.
VB Code:
Public Function Sisic4(ByVal pStr As Long, ByVal pFind As Long, ByVal lenStr As Long, ByVal lenFind As Long) As Long
Dim i As Long
Dim j As Long
Dim Flag As Long
CopyMemory VarPtr(BufStr(0)), ByVal pStr, ByVal lenStr
CopyMemory VarPtr(BufFind(0)), ByVal pFind, ByVal lenFind
i = lenStr - 1
If lenFind = 2 Then
Do Until i < lenFind
If BufStr(i - 1) = BufFind(0) Then
Sisic4 = Sisic4 + 1
End If
i = i - 2
Loop
Else
Do Until i < lenFind
Flag = 0
j = lenFind - 1
Do Until j < 0
If Not (BufStr(i - (lenFind - j)) = BufFind(j - 1)) Then
Flag = -1
Exit Do
End If
j = j - 2
Loop
If Flag = 0 Then
Sisic4 = Sisic4 + 1
End If
i = i - 2
Loop
End If
End Function
.. note the varptr function is used to get the ptr to the first array entry.
Re: argh! count number of full stops??
Compiled the tlb, but I get a Type Mismatch on the VarPtr parameter?
Re: argh! count number of full stops??
Weird!
Have you commented out the existing CopyMemory declare?
Re: argh! count number of full stops??
Yup.
It likes it when I remove all the ByVal keywords, but then when I run my function, it bombs out with a subscript out of range error. Further inspection showed that my i variable had been overwritten with gibberish :sick: