gpt4 book ai didi

c++ - 调用一个空函数会有多浪费?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:55:08 25 4
gpt4 key购买 nike

这三点都涉及同一个“空函数”问题:

  • 调用空函数时浪费了多少处理时间?
  • 调用 100 个甚至 1000 个空函数是否会产生巨大影响?
  • 如果这些空函数需要参数怎么办?

重要修改调用一个空的虚函数是一样的吗?


编辑所以基本上你们都在说在大多数情况下编译器会优化它。

但现在我很好奇,因为这仍然适用于这个问题。如果出现这样的情况,在编译时不知道何时调用空函数怎么办?它会立即进入堆栈然后退出吗?

class base{
public:
virtual void method() = 0;
};

class derived1: public base{
public:
void method() { }
};

class derived2: public base{
public:
void method(){ std::cout << " done something "; }
};


int main()
{
derived1 D1;
derived2 D2;
base* array[] = { &D1, &D2 };
for( int i = 0; i < 1000; i ++)
{
array[0]->method();// nothing
array[1]->method();// Something
}
return 0;
}

最佳答案

虽然它无疑会被任何像样的编译器完全优化,但这里有一个比较。

void EmptyFunction() {}
void EmptyFunctionWithArgs(int a, int b, int c, int d, int e) {}
int EmptyFunctionRet() {return 0;}
int EmptyFunctionWithArgsRet(int a, int b, int c, int d, int e) {return 0;}

int main() {
EmptyFunction();
EmptyFunctionWithArgs(0, 1, 2, 3, 4);
EmptyFunctionRet();
EmptyFunctionWithArgsRet(5, 7, 6, 8, 9);
}

在使用 VC++11 的 Debug模式下(即使有任何优化也很少)调用如下所示:

EmptyFunction();

call    ?EmptyFunction@@YAXXZ            ; EmptyFunction

EmptyFunctionWithArgs(0, 1, 2, 3, 4);

push    4
push 3
push 2
push 1
push 0
call ?EmptyFunctionWithArgs@@YAXHHHHH@Z ; EmptyFunctionWithArgs
add esp, 20 ; 00000014H

EmptyFunctionRet();

call    ?EmptyFunctionRet@@YAHXZ        ; EmptyFunctionRet

EmptyFunctionWithArgsRet(5, 7, 6, 8, 9);

push    9
push 8
push 6
push 7
push 5
call ?EmptyFunctionWithArgsRet@@YAHHHHHH@Z ; EmptyFunctionWithArgsRet
add esp, 20 ; 00000014H

int 返回函数如下所示:

int EmptyFunctionRet()int EmptyFunctionWithArgsRet()

push   ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
xor eax, eax
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0

没有返回值的函数是一样的,只是它们没有xor eax, eax

在 Release模式下 VC++11 不会调用任何函数。但它确实为它们生成了定义。 int 返回函数如下所示:

int EmptyFunctionRet()int EmptyFunctionWithArgsRet()

xor    eax, eax
ret 0

而非返回函数再次删除了 xor eax, eax

您可以很容易地看到,未优化的函数非常臃肿,并且在一个循环中运行它们,无论多少次都绝对会花费时间,而循环本身会在打开优化的情况下被删除。所以帮自己一个忙,发布优化。

您不必担心这一点,因为它违反了“尚不优化”的原则。如果您正在使用一个不起眼的平台(如 27 位 MCU),并且您的编译器是垃圾,并且您的性能需要改进,那么您将分析您的代码以查看您需要改进的地方(它可能不是空函数调用) .就目前而言,这实际上只是一个练习,展示了我们应该让编译器完成多少繁重的工作。

为您的编辑而编辑:

有趣的是,虚函数是优化器的一个已知问题,因为它们很难确定指针的实际去向。一些人为的示例可能会消除调用,但如果存在通过指针的调用,则可能不会被删除。

在 VC++11 Release模式下编译以下内容:

class Object {
public:
virtual void EmptyVirtual() {}
};

int main() {
Object * obj = new Object();
obj->EmptyVirtual();
}

在设置代码中产生以下片段:

mov     DWORD PTR [ecx], OFFSET ??_7Object@@6B@
mov eax, DWORD PTR [ecx]
call DWORD PTR [eax]

这是对虚函数的调用。

关于c++ - 调用一个空函数会有多浪费?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20646579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com