Jer*_*rry 44 c++ variables performance pointers
在求职面试中,我被问到"在C++中如何更快地访问变量,尽管是正常的变量标识符或通过指针".我必须说我对这个问题没有很好的技术答案,所以我做了一个疯狂的猜测.
我说访问时间可能与普通变量相同/标识符是指向存储值的内存地址的指针,就像指针一样.换句话说,就速度而言,它们都具有相同的性能,并且指针只是不同,因为我们可以指定我们希望它们指向的内存地址.
面试官似乎对我的回答并不十分信服/满意(虽然他没有说什么,只是继续问别的东西),因此我来问问他们,我的回答是准确的,如果不是为什么(来自理论和技术POV).
pau*_*sm4 42
当您访问"变量"时,您查找地址,然后获取值.
记住 - 指针是一个变量.实际上,你:
a)查找(指针变量的)地址,
b)获取值(存储在该变量中的地址)
... 然后 ...
c)获取指向的地址的值.
所以是的,通过"指针"(而不是直接)访问DOES涉及(一点点)额外的工作和(略微)更长的时间.
无论它是指针变量(C或C++)还是引用变量(仅限C++),都会发生完全相同的事情.
但差异非常小.
LaC*_*LaC 35
变量不必存在于主存储器中.根据具体情况,编译器可以将其全部或部分存储在寄存器中,访问寄存器比访问RAM要快得多.
dew*_*ell 27
让我们暂时忽略优化,只考虑抽象机器通过(本地)指针引用局部变量与变量的关系.如果我们将局部变量声明为:
int i;
int *p;
Run Code Online (Sandbox Code Playgroud)
当我们引用i的值时,未经优化的代码必须获取(比如说)在当前堆栈指针之后的12处的值并将其加载到寄存器中,以便我们可以使用它.当我们引用*p时,相同的未经优化的代码必须从当前堆栈指针之后的16位获取p的值,将其加载到寄存器中,然后获取寄存器指向的值并将其加载到另一个寄存器中所以我们可以像以前一样使用它.工作的第一部分是相同的,但指针访问在概念上涉及在我们使用值之前需要完成的额外步骤.
那就是,我认为,面试问题的关键点 - 看看你是否理解两种访问类型之间的根本区别.您认为局部变量访问涉及一种查找,它确实 - 但指针访问涉及到相同类型的查找以获取指针的值,然后我们才能开始追踪它指向的东西.在简单的,未经优化的术语中,由于额外的步骤,指针访问将变得更慢.
现在通过优化,可能会发生两次非常接近或相同的情况.确实,如果其他最近的代码已经使用p的值来引用另一个值,那么您可能已经在寄存器中找到了p,因此*p via p的查找与通过堆栈查找i的时间相同指针.但同样地,如果您最近使用了i的值,您可能已经在寄存器中找到它.虽然*p的值可能同样如此,但如果确定p在平均时间内没有改变,则优化器只能从寄存器重用其值.重新使用i的值没有这样的问题.简而言之,虽然在优化下访问这两个值可能需要相同的时间,但访问局部变量几乎不会更慢(除非在真正的病态情况下),并且可能更快.这使得它成为面试官问题的正确答案.
在存在层次结构的情况下,时间上的差异可能会变得更加明显.局部变量将在堆栈中彼此靠近,这意味着您第一次访问时很可能在主内存和缓存中找到所需的地址(除非它是第一个局部变量)你在这个例程中访问).指针指向的地址没有这样的保证.除非最近访问过,否则您可能需要等待缓存未命中甚至页面错误才能访问指向的地址,这可能会使其相对于局部变量减慢数量级.不,这不会一直发生 - 但它是一个可能在某些情况下产生影响的潜在因素,而且这也是候选人在回答这样一个问题时可以提出的.
那么其他评论者提出的问题呢:它有多重要?确实,对于单一访问来说,差异在绝对意义上是微不足道的,就像一粒沙子.但是你把足够的沙粒放在一起,你会得到一个海滩.虽然(继续比喻)如果你正在寻找能够在沙滩路上快速奔跑的人,你不希望有人在他或她开始跑步之前痴迷于扫除路上的每一粒沙子,你我想要一个在他或她不必要地穿过膝盖深处的沙丘时会意识到的人.剖析师不会总是在这里拯救你 - 在这些隐喻的术语中,他们更擅长识别你需要跑来跑去的一块大石头,而不是注意到许多小沙粒会让你失望.因此,我希望我的团队成员能够在基本层面上理解这些问题,即使他们很少使用这些知识.不要在寻求微观优化的过程中停止编写清晰的代码,但要注意可能会降低性能的各种事情,特别是在设计数据结构时,并了解您是否因为支付的价格而获得了良好的价值.这就是为什么我认为这是一个合理的面试问题,以探索候选人对这些问题的理解.
Mar*_*uła 23
什么paulsm4和LaC说+一点asm:
int y = 0;
mov dword ptr [y],0
y = x;
mov eax,dword ptr [x] ; Fetch x to register
mov dword ptr [y],eax ; Store it to y
y = *px;
mov eax,dword ptr [px] ; Fetch address of x
mov ecx,dword ptr [eax] ; Fetch x
mov dword ptr [y],ecx ; Store it to y
另一方面,这并不重要,也可能更难以优化(例如,你不能保持cpu寄存器中的值,因为指针只指向内存中的某个位置).所以y = x的优化代码; 可能看起来像这样:
mov dword ptr [y], ebx - 如果我们假设存储了本地var x ebx
| 归档时间: |
|
| 查看次数: |
22382 次 |
| 最近记录: |