如果我使用int
索引来访问向量元素,它会将整数转换为size_t
,然后调用operator[](size_t)
函数吗?这样做是否会降低性能?
int
和size_t
之间的主要区别是int
是有符号的,而size_t
是无符号的。此外,这两种类型的大小可能不同,因为它们都是特定于平台的并且彼此独立的。
当这两个大小相同时,从int
转换为size_t
是无操作的,因此没有性能影响。
当大小不同时,编译器足够聪明,可以将int
索引的部分或扩展值传递到以size_t
为参数的operator []
中,几乎没有开销,因为缩小大小需要进行部分加载,而扩大大小则需要为上部分加载零。请注意,写入扩展值的上部分的零并不是额外的操作,因为它会替换从size_t
类型的索引复制上部分。
因此,答案是否定的,您不会看到任何性能差异。
int
,因此它进行符号扩展而不是零扩展,在 x86_64 中,符号扩展可能比零扩展效率低得多。 - JSFunsigned
作为索引的数据类型,而不是int
或size_t
。与典型代码相比,我们的代码有更少的情况,编译器可以安全地决定将int
零扩展。我们的代码没有任何包含超过2 ** 31
个元素的容器。 (超过2 ** 32
字节很常见,但超过2 ** 31
个元素还需要几年时间才可能出现)。有些晦涩的情况下,使用unsigned
作为索引需要进行微调,以避免比size_t
慢。但是,有更多的情况下,unsigned
会更快一些,这些情况会累加。 - JSF这要看情况 - size_t
取决于平台。
v[0]
使用了一个int
,显然这是有效的。 - Jonathan Wakelyint
为负数的情况下,在x86_64架构中选择int
和size_t
会有显著的本地性能成本差异(因为符号扩展相对较昂贵)。显著的本地性能差异可能或可能不会导致可检测的全局性能差异。编译器何时检测特定的int
不能为负数?根据我的经验(查看生成的代码),有时候会检测,但比人类明显地少。 - JSFint
可能比size_t
更快。在x86_64中,将32位值复制或计算到64位寄存器中并进行零扩展,始终至少与从64位值复制或计算的相应操作一样快。在某些指令对齐和/或可能出现L1缓存未命中的情况下,使用零扩展的32位复制或计算比从64位值开始要快得多。 - JSF