c++ - 在 C++ 中使用按引用和按值传递的变量的时机

标签 c++ performance-testing

我决定用以下代码比较 C++ (g++ 5.4.0) 中按值传递和按引用传递的时间:

#include <iostream>
#include <sys/time.h>
using namespace std;

int fooVal(int a) {
    for (size_t i = 0; i < 1000; ++i) {
        ++a;
        --a;
    }
    return a;
}
int fooRef(int & a) {
    for (size_t i = 0; i < 1000; ++i) {
        ++a;
        --a;
    }
    return a;
}

int main() {
    int a = 0;
    struct timeval stop, start;
    gettimeofday(&start, NULL);
    for (size_t i = 0; i < 10000; ++i) {
        fooVal(a);
    }
    gettimeofday(&stop, NULL);
    printf("The loop has taken %lu microseconds\n", stop.tv_usec - start.tv_usec);
    gettimeofday(&start, NULL);
    for (size_t i = 0; i < 10000; ++i) {
        fooRef(a);
    }
    gettimeofday(&stop, NULL);
    printf("The loop has taken %lu microseconds\n", stop.tv_usec - start.tv_usec);
    return 0;
}

fooVal 情况相比,预计 fooRef 执行将花费更多时间,因为在 中执行操作时“查找”内存中的引用值>fooRef。但结果证明出乎我的意料:

The loop has taken 18446744073708648210 microseconds
The loop has taken 99967 microseconds

下次我运行代码时,它会产生类似的东西

The loop has taken 97275 microseconds
The loop has taken 99873 microseconds

大部分时间产生的值彼此接近(fooRef 只是稍微慢一点),但有时会像第一次运行的输出那样爆发(对于 >fooReffooVal 循环)。

你能解释一下这个奇怪的结果吗?

UPD:优化已关闭,O0 级。

最佳答案

如果 gettimeofday() 函数依赖于操作系统时钟,那么这个时钟并不是真正为精确处理微秒而设计的。时钟通常会定期更新,并且频率仅足以提供准确显示秒数的外观,以便处理日期/时间值。微秒级别的采样对于基准测试(例如您正在执行的基准测试)可能不可靠。

您应该能够通过延长测试时间来解决此限制;例如,几秒钟。

同样,如其他答案和评论中所述,访问哪种类型的内存(寄存器、高速缓存、主内存等)以及是否应用各种优化的影响可能会对结果产生重大影响。

与解决时间采样限制一样,您可以通过使测试数据集大得多,从而有效地绕过针对较小内存块的内存优化,从而在一定程度上解决内存类型和优化问题。

关于c++ - 在 C++ 中使用按引用和按值传递的变量的时机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42598178/

相关文章:

c++ - #在c++中定义一个特殊的运算符

language-agnostic - 了解何时执行了足够的性能测试迭代的统计方法

testing - 如何使用 JMeter 确定我的 Web 应用程序的断点?

java - jar 在我的机器上速度更快,但在其他机器上速度较慢

java - org.codehaus.jackson.JsonParseException : Unrecognized field '_transferSize' in response element, 通过java读取HAR文件时

c++ - 回调方法显示错误“void(*) 类型的值不能用于初始化类型的实体

c++ - 预处理器 C++ 的工作

结构中的 C++ 函数和通过引用调用值

python - 如何在嵌入式 Python 脚本的错误消息中打印 PyObject 的类型?

web - 如何在网站开发时测试网站的速度