Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Private Server
You last visited: Today at 06:02

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Questions] Faster Methods?

Discussion on [Questions] Faster Methods? within the CO2 Private Server forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
[Questions] Faster Methods?

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 ??

I'm in class so I'll check back later.
Cyah.

Sincerely,
Fang
Spirited is offline  
Old 08/29/2011, 19:21   #2
 
elite*gold: 0
Join Date: May 2011
Posts: 1,769
Received Thanks: 756
First question can be answered here:
Quote:
Originally Posted by CptSky View Post
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.
TargetBuffer.BlockCopyArray.Copymemcpy (void*)memcpy (IntPtr)memcpy (void*, fixed byte*)memcpy (fixed byte*, fixed byte*)
x6431.54730.73430.20130.92234.81729.760
x8643.60641.20837.30937.62640.05137.704
Any28.42227.09725.85826.54230.53126.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.
BaussHacker is offline  
Thanks
1 User
Old 08/29/2011, 19:35   #3


 
Korvacs's Avatar
 
elite*gold: 20
Join Date: Mar 2006
Posts: 6,125
Received Thanks: 2,518
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.
Korvacs is offline  
Thanks
1 User
Old 08/29/2011, 22:50   #4
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
Quote:
Originally Posted by BaussHacker View Post
First question can be answered here:
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
InfamousNoone is offline  
Thanks
2 Users
Old 08/30/2011, 00:50   #5
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
Quote:
Originally Posted by Korvacs View Post
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:
client.Username += ((char)*((char*)(ptr + 4 + i)));
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..
Spirited is offline  
Old 08/30/2011, 01:05   #6
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
Quote:
Originally Posted by Fаng View Post
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.
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);
InfamousNoone is offline  
Thanks
1 User
Old 08/30/2011, 01:31   #7
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
Quote:
Originally Posted by InfamousNoone View Post
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.
Spirited is offline  
Old 08/30/2011, 06:26   #8
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
Not really, I could give you an example on how I handle packets. For example,
Code:
    public unsafe struct MsgWalk
    {
        public static readonly short[] DeltaX = { +0, -1, -1, -1, +0, +1, +1, +1, +0 };
        public static readonly short[] DeltaY = { +1, +1, +0, -1, -1, -1, +0, +1, +0 };

        public short Size;
        public MsgTypeId Type;
        public int Direction;
        public int ObjectId;
        public int MovementId;
        public int TimeStamp;
        public int MapId;

        public void Init(int ObjectId, int Direction, int Id)
        {
            this.Size = (short)sizeof(MsgWalk);
            this.Type = MsgTypeId.Walk;
            this.Direction = Direction;
            this.ObjectId = ObjectId;
            this.MovementId = Id;
            this.TimeStamp = DBCore.GetTime();
        }

        public static void Process(User user, void* pMsg)
        {
            MsgWalk* msg = (MsgWalk*)pMsg;
            if (msg->ObjectId != user.Entity.ObjectId)
                return;

            msg->Direction %= 8;

            int x = user.Entity.X, y = user.Entity.Y;
            if (msg->MovementId == 9)
            {
                user.Socket.Disconnect("MsgWalk::Process steed walking not supported");
                return;
            }
            else
            {
                x += DeltaX[msg->Direction];
                y += DeltaY[msg->Direction];
            }

            user.SendRoom(msg, msg->Size);
            user.Move(x, y);
        }
    }
InfamousNoone is offline  
Old 08/30/2011, 07:09   #9
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,211
Received Thanks: 4,114
That's how i code packets too (kind of).
What do u think of a packet queue at the receive void?
Spirited is offline  
Reply


Similar Threads Similar Threads
[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??
T>aegis duping methods for eAthena methods
03/21/2009 - Ragnarok Online - 0 Replies
pm for details



All times are GMT +2. The time now is 06:02.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.