简体   繁体   中英

C++ most optimal conversion

Is that most optimal for server (speed) conversion of data ?

Could I change it for better performance ?

This is used in packet parser to set/get packet data.

void Packet::setChar(char val, unsigned int offset)
{
    raw[offset + 8] = val;
}

short Packet::getChar(unsigned int offset)
{
    return raw[offset + 8];
}

void Packet::setShort(short val, unsigned int offset)
{
    raw[offset + 8] = val & 0xff;
    raw[offset + 9] = (val >> 8)  & 0xff;
}

short Packet::getShort(unsigned int offset)
{
    return (short)((raw[offset + 9]&0xff) << 8) | (raw[offset + 8]&0xff);
}

void Packet::setInt(int val, unsigned int offset)
{
    raw[offset + 8] = val & 0xff;
    raw[offset + 9] = (val >> 8)  & 0xff;
    raw[offset + 10] = (val >> 16) & 0xff;
    raw[offset + 11] = (val >> 24) & 0xff;
}

int Packet::getInt(unsigned int offset)
{
    return (int)((raw[offset + 11]&0xff) << 24) | ((raw[offset + 10]&0xff) << 16) | ((raw[offset + 9]&0xff) << 8) | (raw[offset + 8]&0xff);
}

Class defs :

class Packet
{
    public:
        Packet(unsigned int length);
        Packet(char * raw);
        ///header

        void setChar(char val, unsigned int offset);
        short getChar(unsigned int offset);

        void setShort(short val, unsigned int offset);
        short getShort(unsigned int offset);

        void setInt(int val, unsigned int offset);
        int getInt(unsigned int offset);

        void setLong(long long val, unsigned int offset);
        long getLong(unsigned int offset);

        char * getRaw();

        ~Packet();
    protected:
    private:
        char * raw;
};

@EDIT added class definitions Char raw is inirialized with packet (new char).

It looks like that your implementation is already almost as efficient as possible. It simply isn't possible to optimize it further without a major overhaul of the application and even then, you'll save only few CPU cycles.

By the way, make sure that the function definitions are present in the header file, or #included to it. Otherwise, each output operation will need a function call, which is quite expensive for what you're doing.

I do agree with the comments saying "if it's not shown to be a problem, don't change it".

If your hardware is little endian, AND you either know that the offset is always aligned, or the processor supports unaligned accesses (eg x86), then you could speed up the setting of the larger data types by simply storing the whole item in one move (and yes, there will probably be people saying "it's undefined" - and it may well be undefined, but I've yet to see a compiler that doesn't do this correctly, because it's a fairly common thing to do in various types of code).

So something like this:

void Packet::setInt(int val, unsigned int offset)
{
    int *ptr = static_cast<int*>(&raw[offset + 8]); 
    *ptr = val;
}

void Packet::getInt(int val, unsigned int offset)
{
    int *ptr = static_cast<int*>(&raw[offset + 8]); 
    return *ptr;
}

Another thing I would DEFINITELY do is to ensure that the functions are present in a headerfile, so that the compiler has the choice to inline the functions. This will quite likely give you MORE benefit than fiddling with the code inside the functions, because the overhead of calling a function vs. being able to use the function inline will be quite noticeable. So that would be my first step - assuming you think it is a problem in the first place. For most things, stuffing the data into the buffer is not the "slow part" of sending a data packet - it is either the forming of the content, or the bytes passing down the wire to the other machine (which of the two depends on how fast your line is, and what calculations go into preparing the data in the first place).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM