1

这对于数据的服务器(速度)转换是最优化的吗?

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

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

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 用数据包(新字符)初始化。

4

2 回答 2

1

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

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

于 2013-08-30T19:49:37.930 回答
1

我同意评论说“如果它没有被证明是一个问题,就不要改变它”。

如果您的硬件是 little endian,并且您知道偏移量始终是对齐的,或者处理器支持未对齐的访问(例如 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;
}

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

于 2013-08-30T19:54:52.750 回答