【发布时间】:2014-09-17 17:31:52
【问题描述】:
这取决于字符串的长度,所以让我们采用 3 种情况:最简单的情况、最坏的情况和中间的情况。全部为 32 位无符号整数。值将是 0、4294967295 和 67295(半长字符串)。
假设它在现代 CPU 上运行,例如 i7 Nehalem。
我想用具体的数字来说明这个操作对 CPU 的占用程度。该算法通常是一个小循环,其中一次迭代需要前一次的结果,因此代码不会利用超标量 CPU 优化。
是否有任何硬接线指令可以在现代 CPU 上执行此操作?
编辑:我试图回答自己并进行了一些搜索。
使用Agner Fog's 'Instruction Tables' 和来自this answer 的代码
;parameters esi is a pointer to the string, ecx the length of the string
string_to_int: ;
xor ebx,ebx ; clear ebx > 1,1
.next_digit:
movzx eax,byte[esi] ; > 1,1
inc esi ; > 1,1
sub al,'0' ; convert from ASCII to number > 1,1
imul ebx,10 ; > 1,3
add ebx,eax ; ebx = ebx*10 + eax > 1,1
loop .next_digit ; while (--ecx) > 6
mov eax,ebx ; > 1,1
ret
第一条和最后一条指令运行一次。其他延迟和执行的总和是每次迭代 18。所以问题的答案应该是4+18*string.length。
- “0” = 22 个周期
- “4294967295” = 184 个周期
- “67295” = 94 个周期
这比我想象的要少得多。这仅用于转换,不计算处理字符串所需的所有操作:从 NIC 缓冲区复制到内存,内存到 CPU 缓存...
我算对了吗?有没有微优化专家可以告诉我这看起来是否正确? (也许是神秘的?;))
【问题讨论】:
-
@Cratylus :关于如何将字符串转换为 int 有很多问题,但它不计算 CPU 周期(sub、mul、add 有多少个 cyles...)
-
计算机使用字节,字符串用于人类。转换需要多长时间无关紧要,它总是比所需的 I/O 快 很多。
-
目前有 4 种不同的 i7 基础架构(Nehalem、Sandy Bridge、Ivy Bridge、Haswell,不包括 Haswell-E),另外两种已经展示(Broadwell、Skylake)。您的问题笼统地概括了太多。如何找出来很容易。测量它。
-
@HansPassant 今天在网络服务器上完成的大部分转换都是针对 XML 和 JSON 序列化的。浏览器/网络服务使用者 前端服务器 SQL 数据库。我想知道为什么这个问题值得反对。