C ++最优化的转换

时间:2013-08-30 19:30:57

标签: c++ int type-conversion

这对于数据的服务器(速度)转换是否最合适?

我可以更改它以获得更好的性能吗?

这在数据包解析器中用于设置/获取数据包数据。

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 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添加了类定义 使用数据包(新字符)对Char raw进行初始化。

2 个答案:

答案 0 :(得分:1)

看起来你的实现已经几乎尽可能高效了。如果没有对应用程序进行大修,那么就不可能进一步优化它,即使这样,你也只能节省几个CPU周期。

顺便说一句,确保函数定义存在于头文件中,或#included到它。否则,每个输出操作都需要一个函数调用,这对你正在做的事情来说非常昂贵。

答案 1 :(得分:1)

我同意评论说“如果没有显示出问题,请不要改变它”。

如果您的硬件是小端,并且您要么知道偏移始终是对齐的,要么处理器支持未对齐的访问(例如x86),那么您可以通过简单地存储整个项目来加速更大数据类型的设置一举一动(是的,可能会有人说“它是未定义的” - 而且很可能是未定义的,但我还没有看到编译器没有正确地执行此操作,因为这是相当常见的事情在各种类型的代码中)。

这样的事情:

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;
}

我绝对要做的另一件事是确保函数存在于头文件中,以便编译器可以选择内联函数。这很可能比摆弄函数内部的代码更有益,因为调用函数与能够使用函数内联的开销将非常明显。所以这将是我的第一步 - 假设你认为这首先是一个问题。对于大多数情况来说,将数据填充到缓冲区并不是发送数据包的“缓慢部分” - 它要么是内容的形成,要么是通过线路传递到另一台机器的字节(两者中的哪一个取决于您的生产线有多快,以及首先准备数据的计算方法)。