这取决于字符串的长度,所以让我们看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。
远远低于我的想法。这仅用于转换,不计算处理字符串所需的所有操作:从NIC缓冲区复制到ram,ram到CPU缓存......
我算数正确吗?是否有任何微型优化专家可以告诉我这看起来是否合适? (神秘可能?;))
答案 0 :(得分:1)
您必须将字符串转换为整数值的算法是通常接受的算法(32位)。但是,有一种以上的算法可以将整数值转换为字符串(更不用说指令集,微体系结构,缓存大小等等)。即使你限制了这些事情的每一个,也没有任何一个答案可以回答这个问题。
虽然,我认为这可能是过早优化的情况。如果我理解正确,您就会关注非二进制协议引入的额外开销。二进制协议通常是提高性能所采取的极端措施。它通常也用于限制延迟,而不是增加吞吐量。
使用二进制协议(压缩特性,易用性,易于调试等等),您不得不放弃使用的文本协议有很多好处。您还需要考虑并非所有CPU架构都是little-endian(网络字节顺序特别是big-endian)。在优化之前确保协议是瓶颈。
答案 1 :(得分:0)
解释XML文件的内容会消耗大量的CPU周期。较大的一个将需要CPU秒或更长时间来解析。如果将大型XML文件保留为数据库数据库,那么平均而言,查找数据的时间比将数据转换为此数字或数字格式要长数百万倍。
Ergo,(如果可能的话)将文件一次性转换为矢量,矩阵或其他可轻松索引的二进制值结构。如果无法建立索引,只需在向量中查找数据比在XML文件中执行相同操作要快得多。在任何情况下,即使在一次性转换中,在XML文件中查找数据的工作也会比在您找到它后转换的工作大得多。
关于你的问题本身,我猜测每循环10个(更接近)15个循环。我已经读过,循环[cond]指令是早期处理器代的遗留物,可能在Pentium引入时已经停止使用。 gcc的汇编输出确认它很少使用。根据我的理解,它具有不容易重新排序的指令,并且它测试在指令开始执行时可能不可用的状态标志,从而导致处理器停顿。它的结果(跳跃)应该是相当可预测的。