【发布时间】:2009-11-06 01:49:13
【问题描述】:
我需要一个内存块比较函数,以便在 D 编程语言中对字节数组进行二进制搜索。它不需要任何有用的语义。它只需要快速并且是有效的比较函数(产生总排序的函数)。已知要比较的内存块长度相同。
C 的memcmp 实际上很慢,因为它试图保留有用的字符串比较语义,而我不需要。以下是迄今为止我想出的最好的。有没有人知道更好的东西,最好是不使用非便携式 CPU 特定指令?
// Faster than C's memcmp because it doesn't preserve any meaningful
// semantics. It's just a completely arbitrary, but really fast,
// comparison function.
int memoryCompare(const(void)* lhs, const(void)* rhs, size_t n) {
for(; n >= uint.sizeof; n -= uint.sizeof) {
if( *(cast(uint*) lhs) < *(cast(uint*) rhs)) {
return -1;
} else if( *(cast(uint*) lhs) > *(cast(uint*) rhs)) {
return 1;
}
lhs += uint.sizeof;
rhs += uint.sizeof;
}
for(; n >= ubyte.sizeof; n -= ubyte.sizeof) {
if( *(cast(ubyte*) lhs) < *(cast(ubyte*) rhs)) {
return -1;
} else if( *(cast(ubyte*) lhs) > *(cast(ubyte*) rhs)) {
return 1;
}
lhs += ubyte.sizeof;
rhs += ubyte.sizeof;
}
return 0;
}
编辑:我已经阅读了 SSE,但出于 3 个原因不想使用它:
- 它不是便携式的。
- 需要在 ASM 中编程。
- 比较指令假定您的数据是浮点数,如果某些数据恰好与 NaN 的模式匹配,这可能会出现问题。
【问题讨论】:
-
也许:faydoc.tripod.com/cpu/scasb.htm (x86)
-
如果你想要真正的低级,你可以尝试使用 rep cmpsb、rep cmpsd 甚至 SSE 比较的内联汇编。
-
Re “C 的 memcmp 实际上很慢,因为它试图保留有用的字符串比较语义”。您当然是在讨论特定的实现,但总的来说,在现代 CPU 上
memcmp受限于您访问内存的速度。没有比这更好的算法了,可证明。 -
什么意思,“C 的 memcmp 实际上很慢,因为它试图保留有用的字符串比较语义”?这听起来更像
strncmp()而不是memcmp()。请显示基准测试表明您的版本(因为它甚至不是 C 语言而无法编译)比现代 C 标准库的内置memcmp()更快。 -
我将其重新标记为“d”。代码都是d,所以我不确定为什么它被标记为“c”。当然,如果不是拼写错误,请随意将其改回,但这可能会让读者感到困惑,并认为您的代码有误。
标签: performance algorithm d binary-search low-level