Hey everyone.
So I've been working with pointers and I was wondering what's faster and if their are any alternative methods that might speed up my server.
1. Buffer.BlockCopy VS an unsafe for loop.
2. Encoding.ASCII.GetString VS an unsafe for loop with System.Convert.ToChar
3. Marshal.AllocHGlobal VS ??
Managed vs Unmanaged in C#... I know these things, but it will give a better idea of the reality and you'll see that the difference is so little that you can use what you want...
Tested on Windows XP x64, for a copy of 50'000'000 elements and tested 1000 times for precision. All values in ms.
Target
Buffer.BlockCopy
Array.Copy
memcpy (void*)
memcpy (IntPtr)
memcpy (void*, fixed byte*)
memcpy (fixed byte*, fixed byte*)
x64
31.547
30.734
30.201
30.922
34.817
29.760
x86
43.606
41.208
37.309
37.626
40.051
37.704
Any
28.422
27.097
25.858
26.542
30.531
26.087
Results:
Allocating managed resources takes more times than unmanaged resources.
Byte[] = new Byte[], Byte* = (Byte*)Marshal.AllocHGlobal()
x64 is fastest than x86 on 64 bits OS.
Any CPU is fastest than x64 on 64 bits OS and probably on 32 bits OS (x86).
Array.Copy is fastest than Buffer.BlockCopy.
There is no difference between void* and IntPtr.
There is no difference between fixed pointer and pointer.
Native function memcpy is fastest than Array.Copy.
Blockcopy's alternative should be memcpy, not a loop, pretty sure blockcopy and arraycopy both use memcpy within the methods.
For converting to a string you could do something like this within a for loop:
Code:
newstring += (char)*((char*)(lpBuffer + x);
Marshal.AllocHGlobal... i guess you could call LocalAlloc directly from kernel32, although i dont believe theres really much difference between the 2 methods, it just nicely wraps the call for you, possibly with some additional checks, i havent looked at the source.
Buffer.ArrayCopy and Array.Copy need to be JIT-compiled on their first invoke, so performance is lost there. Secondly, if you constantly need to fix-down a pointer (using a fixed statement), it'll obviously result in a slight loss of performance.
Generally speaking, and depending on what your using it for, malloc() (in msvcrt.dll) will do a better job than AllocHGlobal will (in kernel32.dll).
If you need a small (we're talking like, under 255-bytes) temporary pointer-variable until the end of your method, I'd use stackalloc.
You should look at string.ctor(sbyte* ptr, int offset, int length) btw
Marshal.AllocHGlobal... i guess you could call LocalAlloc directly from kernel32, although i dont believe theres really much difference between the 2 methods, it just nicely wraps the call for you, possibly with some additional checks, i havent looked at the source.
Code:
newstring += (char)*((char*)(lpBuffer + x);
I tried it already. It returns: "慆湡杮g" instead of "Fang"
The only thing that I found that worked with unsafe code was
"client.Username += System.Convert.ToChar(*(ptr + 4 + i));"
I'm guessing it's slightly better (I hope) than Encoding.ASCII.
edit: looking at string.ctor(sbyte* ptr, int offset, int length) now..
I tried it already. It returns: "慆湡杮g" instead of "Fang"
The only thing that I found that worked with unsafe code was
"client.Username += System.Convert.ToChar(*(ptr + 4 + i));"
I'm guessing it's slightly better (I hope) than Encoding.ASCII.
A character in C# is 2-bytes (a wchar_t) in C++
A 'char' in C++ is a single-byte value (equivalent to a sbyte in C#)
The string send is a multi-byte string meaning, each character has a value of 1 byte. Therefore, by making a pointer type of C#'s 'char' type (2 bytes), you get these odd unicode characters.
Code:
string result = new string((sbyte*)ptr, offset, length);
A character in C# is 2-bytes (a wchar_t) in C++
A 'char' in C++ is a single-byte value (equivalent to a sbyte in C#)
The string send is a multi-byte string meaning, each character has a value of 1 byte. Therefore, by making a pointer type of C#'s 'char' type (2 bytes), you get these odd unicode characters.
Code:
string result = new string((sbyte*)ptr, offset, length);
Just saw your post.
Thanks for the C++ lesson =p
Any other tips on pointers? I'd really like to use them more.
[QUESTIONS] How to get GP faster in GCPH? 08/22/2010 - Grand Chase Philippines - 12 Replies Where to get GP faster in GCPH? i know that the answer is only at the dungeon but what dungeon is it??