|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
API Declarations...just curious.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. Lance wrote:
Show quoteHide quote > Hi all, Can you please post a complete example of this (including your method> > 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 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 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?code/fileapi/recursivefiles_minimal_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 Show quoteHide quote "Tom Shelton" <t**@mtogden.com> wrote in message news:1158337819.685691.24450@e3g2000cwe.googlegroups.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 > 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. Thanks for the info Mattias.
Lance Show quoteHide quote "Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote in message news:%23tQYm5Y2GHA.4588@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. |
|||||||||||||||||||||||