我主要是一名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#中重写它?
答案 0 :(得分:2)
C#是一种具有指针的语言,但也有引用(和references are not necessarily addresses)。 C#中的byte[]
等数组是表示在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
作为其限制检查(ref:Eric Gunnerson: Efficiency of iteration over arrays),因为这可以通过JIT针对数组长度进行优化。如果使用单独的长度参数则不能,因此应避免这种情况(或者如果所需的迭代次数可能小于数组长度,则应与长度结合使用)。
答案 1 :(得分: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;
}