0

我主要是一名 C++ 程序员,但在业余时间,我试图加快 C# 的速度。我有以下要转换的 C++ 函数-

#define COMPUTE_CRC32(cp,crc) (crc32lookup_table[((unsigned long)crc^(unsigned char)cp)&0xff]^(((unsigned long)crc>>8)&0x00FFFFFF))

unsigned long ComputeCRC32::Update(const void* ptrBytes, long numBytes)
{
    const unsigned char* ptr_data = (const unsigned char*) ptrBytes;

    while ( --numBytes >= 0 )
    {
        unsigned char data_byte = *ptr_data++ ; 

        m_ulCRC = COMPUTE_CRC32( data_byte, m_ulCRC );
    }

    return m_ulCRC;
}

我知道有很多方法可以做到这一点,但想看看最好的方法是什么。这是我迄今为止创造的 -

public uint Update(object ptrBytes, int numBytes)
{
    byte * ptr_data = (byte) ptrBytes;

    while (--numBytes >= 0)
    {
        byte data_byte = *ptr_data++;

        m_ulCRC = (GlobalMembersComputeCRC32.crc32lookup_table[((uint)m_ulCRC ^ (byte)data_byte) & 0xff] ^ (((uint)m_ulCRC >> 8) & 0x00FFFFFF));
    }

    return m_ulCRC;
}

转换指针的最佳方法是什么?有没有更好的方法在 C# 中重写它?

4

2 回答 2

2

C# 是一种有指针的语言,但也有引用(并且引用不一定是地址)。诸如byte[]C# 中的数组是表示您可能在 C++ 中使用指针的常用方法。

要使用指针,请使用unsafe. 如果你在 C# 中思考,人们倾向于避免unsafe,因为它通常是“不安全的”;相反,运行时会强制执行检查以避免数组中的缓冲区溢出之类的事情。相反,Crc32 的伪代码可能是:

public uint Crc32(byte[] data) {
  uint result;
  for (int i= 0; i < data.Length; i++) {
    byte data_byte = data[i];
    result = doCrc(...stuff with data_byte...);
  }
  return result;
}

请注意,for循环data.Length用作其限制检查(参考:Eric Gunnerson:数组迭代的效率),因为这可以通过 JIT 针对数组长度进行优化。如果您使用单独的长度参数,则不能使用,因此应避免这种情况(或与长度结合,如果所需的迭代计数可能小于数组长度)。

于 2013-11-11T21:23:14.297 回答
0

这些指针没有做任何棘手的事情。它们只是数组迭代器。

public uint Update( byte[] ptrBytes, int numBytes )
{
    for( int i = 0; i < numBytes; i++ )
    {
        byte data_byte = ptr_data[i];
        m_ulCRC = ...
    }

    return m_ulCRC;
}
于 2013-11-11T21:14:40.673 回答