【发布时间】:2013-02-07 17:12:56
【问题描述】:
假设我有以下代码
void f(PolymorphicType *p)
{
for (int i = 0; i < 1000; ++i)
{
p->virtualMethod(something);
}
}
编译器生成的代码是否会对p 的vtable 条目取消引用virtualMethod 1 或1000 次?我正在使用微软的编译器。
编辑
这是为我正在查看的真实案例生成的程序集。 line->addPoint() 是关注的虚拟方法。我没有组装经验,所以慢慢复习……
; 369 : for (int i = 0; i < numPts; ++i)
test ebx, ebx
je SHORT $LN1@RDS_SCANNE
lea edi, DWORD PTR [ecx+32]
npad 2
$LL3@RDS_SCANNE:
; 370 : {
; 371 : double *pts = pPoints[i].SystemXYZ;
; 372 : line->addPoint(pts[0], pts[1], pts[2]);
fld QWORD PTR [edi+8]
mov eax, DWORD PTR [esi]
mov edx, DWORD PTR [eax+16]
sub esp, 24 ; 00000018H
fstp QWORD PTR [esp+16]
mov ecx, esi
fld QWORD PTR [edi]
fstp QWORD PTR [esp+8]
fld QWORD PTR [edi-8]
fstp QWORD PTR [esp]
call edx
add edi, 96 ; 00000060H
dec ebx
jne SHORT $LL3@RDS_SCANNE
$LN314@RDS_SCANNE:
; 365 : }
【问题讨论】:
-
要求编译器生成汇编代码并检查。
-
用优化编译它并查看生成的代码。
-
添加到 Joachim 的评论中 - 除了检查之外没有其他方法。
-
我不确定编译器在这里也可以假设什么。调用 ->virtualFunction 可以 改变 p 指向的东西,如果 p 指向的对象被删除并在不同子类型的该位置创建一个新对象怎么办? (我不知道这是否可行或合法,但这是编译器编写者在生成代码时必须考虑的事情......),他们必须非常小心他们的假设......
-
好的,所以
mov edx, DWORD PTR [eax+16]...call edx在循环内。我猜它每次都在看 vtable。
标签: c++ performance polymorphism vtable