473,325 Members | 2,816 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

API Declarations...just curious.

Hi all,

I'm curious as to the technicalities of why a particular method declaring and calling is
faster than the other. The C syntax is:

\\\\\
BOOL PathMatchSpec(
LPCSTR pszFile,
LPCSTR pszSpec
);
\\\\\

In VB2005, I'm declaring and then calling an API function as such:

\\\\\
Private Declare Auto Function PathMatchSpec Lib "shlwapi" _
(ByVal pszFileParam As IntPtr, _
ByVal pszSpec As IntPtr) As Boolean

Private Function MatchSpec(ByVal sFile As String, ByVal sSpec As String) As Boolean
Dim FilePtr As IntPtr = Marshal.StringToHGlobalAuto(sFile)
Dim SpecPtr As IntPtr = Marshal.StringToHGlobalAuto(sSpec)
Dim Match As Boolean
Match = PathMatchSpec(FilePtr, SpecPtr)
Marshal.FreeHGlobal(FilePtr)
Marshal.FreeHGlobal(SpecPtr)
Return Match
End Function
\\\\\

This (the above example) runs nearly 20% faster over the course of about 190,000 calls
than declaring and calling it as such:

\\\\\
Private Declare Auto Function PathMatchSpec Lib "shlwapi" _
(ByVal pszFileParam As String, _
ByVal pszSpec As String) As Boolean

Private Function MatchSpec(ByVal sFile As String, ByVal sSpec As String) As Boolean
Return PathMatchSpec(sFile, sSpec)
End Function
\\\\\

With all the marshaling in the first example, I would have thought there would have been
some significant overhead going on compared to the second example.
Sep 15 '06 #1
4 1534

Lance wrote:
Hi all,

I'm curious as to the technicalities of why a particular method declaring and calling is
faster than the other. The C syntax is:

\\\\\
BOOL PathMatchSpec(
LPCSTR pszFile,
LPCSTR pszSpec
);
\\\\\

In VB2005, I'm declaring and then calling an API function as such:

\\\\\
Private Declare Auto Function PathMatchSpec Lib "shlwapi" _
(ByVal pszFileParam As IntPtr, _
ByVal pszSpec As IntPtr) As Boolean

Private Function MatchSpec(ByVal sFile As String, ByVal sSpec As String) As Boolean
Dim FilePtr As IntPtr = Marshal.StringToHGlobalAuto(sFile)
Dim SpecPtr As IntPtr = Marshal.StringToHGlobalAuto(sSpec)
Dim Match As Boolean
Match = PathMatchSpec(FilePtr, SpecPtr)
Marshal.FreeHGlobal(FilePtr)
Marshal.FreeHGlobal(SpecPtr)
Return Match
End Function
\\\\\

This (the above example) runs nearly 20% faster over the course of about 190,000 calls
Can you please post a complete example of this (including your method
of timing)? I am not seeing much of a difference at all. Over a
190,000 calls I'm only seeing about a .00008 second difference...

--
Tom Shelton

Sep 15 '06 #2
Hi Tom,

I knew you'd be the first to reply to an API question :-)

My method of timing uses:

\\\\\
Private Declare Auto Function GetTickCount Lib "kernel32" () As Int32
\\\\\

right before and after the start of the loop, then calculates the diference.

BTW, I'm an idiot and I missposted something: 190,000 returned True from the function
call, but the function iteself was called 1,040,528 times. Also, LAN conditions are
likely effecting this as well; the 20% figure I gave earlier is an average over the course
of testing on different days at different times.

FWIW, the loop is not a test loop (i.e., x = 1 to 190000) but a loop that includes
searching for all files (*.*) on a network of which 190,000 fit the sSpec and return True.
Also, the sSpec string contains 44 different file types (i.e. "*. txt; *.log; *.
doc;....." etc.). I suppose these factors may effect the results.

As for the rest of the code, it's a VB.Net-ized version of
http://vbnet.mvps.org/index.html?cod...l_multiple.htm. Not
all that much has changed from the code you see on that page, except for the types and the
declarations (which you provided in a previous answer to a posting of mine), including the
variations I posted in my original message.

Lance
"Tom Shelton" <to*@mtogden.comwrote in message
news:11*********************@e3g2000cwe.googlegrou ps.com...
>
Lance wrote:
>Hi all,

I'm curious as to the technicalities of why a particular method declaring and calling
is
faster than the other. The C syntax is:

\\\\\
BOOL PathMatchSpec(
LPCSTR pszFile,
LPCSTR pszSpec
);
\\\\\

In VB2005, I'm declaring and then calling an API function as such:

\\\\\
Private Declare Auto Function PathMatchSpec Lib "shlwapi" _
(ByVal pszFileParam As IntPtr, _
ByVal pszSpec As IntPtr) As Boolean

Private Function MatchSpec(ByVal sFile As String, ByVal sSpec As String) As Boolean
Dim FilePtr As IntPtr = Marshal.StringToHGlobalAuto(sFile)
Dim SpecPtr As IntPtr = Marshal.StringToHGlobalAuto(sSpec)
Dim Match As Boolean
Match = PathMatchSpec(FilePtr, SpecPtr)
Marshal.FreeHGlobal(FilePtr)
Marshal.FreeHGlobal(SpecPtr)
Return Match
End Function
\\\\\

This (the above example) runs nearly 20% faster over the course of about 190,000 calls

Can you please post a complete example of this (including your method
of timing)? I am not seeing much of a difference at all. Over a
190,000 calls I'm only seeing about a .00008 second difference...

--
Tom Shelton

Sep 15 '06 #3
Lance,

I don't think it's a very good idea to involve network IO in your
benchmark. There are so many other factors that affect performance
when you involve a network connection (such as caching, network load
etc).

I tried code similar to yours on different declarations of another API
- lstrcmp - that has almost the same signature as PathMatchSpec.

Declare Auto Function lstrcmp1 Lib "kernel32.dll" Alias "lstrcmp"
(ByVal lpString1 As String, ByVal lpString2 As String) As Integer

Declare Auto Function lstrcmp2 Lib "kernel32.dll" Alias "lstrcmp"
(<MarshalAs(UnmanagedType.LPTStr)ByVal lpString1 As String,
<MarshalAs(UnmanagedType.LPTStr)ByVal lpString2 As String) As
Integer

Declare Auto Function lstrcmp3 Lib "kernel32.dll" Alias "lstrcmp"
(ByVal lpString1 As IntPtr, ByVal lpString2 As IntPtr) As Integer

For 1,000,000 iterations timed with the .NET 2.0 StopWatch class I got
the following results

1: 882 msec
2: 198 msec
3: 1525 msec

So in this case the clear winner is declaring the parameters as String
and adding the MarshalAs(LPTStr) attribute to avoid VB's default
MarshalAs(VBByrefStr) which causes unnecessary copying to preserve
classic VB behaviour. The third, DIY method is by far the slowest like
I would expect, since it involves the most managed/native transitions.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Sep 16 '06 #4
Thanks for the info Mattias.

Lance

"Mattias Sjögren" <ma********************@mvps.orgwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
Lance,

I don't think it's a very good idea to involve network IO in your
benchmark. There are so many other factors that affect performance
when you involve a network connection (such as caching, network load
etc).

I tried code similar to yours on different declarations of another API
- lstrcmp - that has almost the same signature as PathMatchSpec.

Declare Auto Function lstrcmp1 Lib "kernel32.dll" Alias "lstrcmp"
(ByVal lpString1 As String, ByVal lpString2 As String) As Integer

Declare Auto Function lstrcmp2 Lib "kernel32.dll" Alias "lstrcmp"
(<MarshalAs(UnmanagedType.LPTStr)ByVal lpString1 As String,
<MarshalAs(UnmanagedType.LPTStr)ByVal lpString2 As String) As
Integer

Declare Auto Function lstrcmp3 Lib "kernel32.dll" Alias "lstrcmp"
(ByVal lpString1 As IntPtr, ByVal lpString2 As IntPtr) As Integer

For 1,000,000 iterations timed with the .NET 2.0 StopWatch class I got
the following results

1: 882 msec
2: 198 msec
3: 1525 msec

So in this case the clear winner is declaring the parameters as String
and adding the MarshalAs(LPTStr) attribute to avoid VB's default
MarshalAs(VBByrefStr) which causes unnecessary copying to preserve
classic VB behaviour. The third, DIY method is by far the slowest like
I would expect, since it involves the most managed/native transitions.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Sep 18 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Michael Tobis | last post by:
Summary of my understanding of a recent interesting thread: General usage has "declaration" meaning "statement which does not generate executable bytecode but merely affects the compiler". My...
11
by: aleko | last post by:
This applies equally to function prototypes. Why do we have to tell the compiler twice? Other modern compiled languages don't have this requirement. Just curious, Aleko
134
by: James A. Donald | last post by:
I am contemplating getting into Python, which is used by engineers I admire - google and Bram Cohen, but was horrified to read "no variable or argument declarations are necessary." Surely that...
14
by: Arthur J. O'Dwyer | last post by:
Well, I'm trying to write that program that was requested a few weeks back, the one that could take struct definitions and create portable functions to read and write those structs. Hence the...
28
by: Michael B. | last post by:
I tend to use rather descriptive names for parameters, so the old style of declaration appeals to me, as I can keep a declaration within 80 chars: void * newKlElem...
8
by: Simon Brooke | last post by:
I was debugging a new XML generator tonight and trying to determine why it wasn't working; and realised my dom printer does not output XML namespace declarations. My method to output an Element...
2
by: raylopez99 | last post by:
I'm having problems compiling complex reference declarations in MSVC++.NET 2002 IDE. Here is an example: // --Foo.h-- #include "Bar.h" class Bar; //forward decl. to a class Bar in...
3
by: Juha Nieminen | last post by:
I once made my own smart pointer implementation for a project and at one point fought to death to find a malicious bug. The program was not working and I couldn't figure out why. The source of the...
5
by: John Williams | last post by:
I've been spending some time expanding my rather primitive knowledge of c++ through various exercises. One of them that I've been working on is learning a bit about how compression works. I've...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.