【问题标题】:Global values inside template function not changing [c++]模板函数内的全局值不变[c++]
【发布时间】:2013-03-14 07:17:18
【问题描述】:

我需要一个项目的帮助。基本上我需要测量一些排序算法的时钟滴答声。由于它们都使用比较,有时还使用交换函数,因此我将它们设计为接受这些作为回调函数。

为了测量我写的时钟滴答声:

static clock_t t1, total;

template<typename T>
bool less_default(T & left, T & right){
    t1 = clock(); 
    bool v = left < right; 
    t1 = clock() - t1;
    total += t1
    return v;
}

当我实际运行算法时,total 或 t1 都没有反映任何变化。就好像引用它们的代码行从来没有写过一样。

没有任何作用。函数调用时甚至不是简单整数的增量。

是不是静态全局变量不能在模板函数内部改变?

我不明白我在这里做错了什么。

【问题讨论】:

  • 您是从同一个文件调用的吗?它在 .h 文件中吗?
  • 考虑将 static 更改为 extern 并在 main() 源文件(或一些其他合适的位置)。
  • 考虑衡量一百万个对象的比较,而不是一个对象。请使用除全局变量之外的其他内容。
  • 当 T 是一个非常大的数组并且比较每个元素时,我确信刻度应该大于 0。然而这并没有发生。
  • 你怎么知道刻度不大于零?您有多个相同值的副本。你在增加哪一个?你检查的是哪一个?是同一个吗?你怎么知道?你能把递增的函数与打印值的函数联系起来吗?

标签: c++ function templates variables global


【解决方案1】:

没有任何作用。函数调用时甚至不是简单整数的增量。

我怀疑以下内容出现在 header 文件中:

static clock_t t1, total;

如果是这种情况,每个翻译单元都会获得两个变量的单独实例(感谢static)。

要解决此问题,请将标头中的 static 更改为 extern,并将以下内容添加到 .cpp 文件中:

clock_t t1, total;

编辑示例如下:

根据 OP 的要求,这是一个简短的示例,它使用模板比较器和此答案中的配方来声明和管理运行时钟总数。

ma​​in.h

#ifndef PROJMAIN_DEFINED
#define PROJMAIN_DEFINED

extern clock_t total;

template<typename T>
bool less_default(const T& left, const T& right)
{
    clock_t t1 = clock();
    bool res = (left < right);
    total += (clock() - t1);
    return res;
};

#endif

ma​​in.cpp

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include "main.h"
using namespace std;

clock_t total = 0;

int main()
{
    static const size_t N = 2048;
    vector<int> values;
    values.reserve(N);
    std::srand((unsigned)time(0));

    cout << "Generating..." << endl;
    generate_n(back_inserter(values), N, [](){ static int i=0; return ++i;});

    for (int i=0;i<5;++i)
    {
        random_shuffle(values.begin(), values.end());
        cout << "Sorting ..." << endl;
        total = 0;
        std::sort(values.begin(), values.end(), less_default<int>);
        cout << "Finished! : Total = " << total << endl;
    }
    return EXIT_SUCCESS;
}

输出

Generating...
Sorting ...
Finished! : Total = 13725
Sorting ...
Finished! : Total = 13393
Sorting ...
Finished! : Total = 15400
Sorting ...
Finished! : Total = 13830
Sorting ...
Finished! : Total = 15789

【讨论】:

  • 确实如此。但是,将其更改为普通的全局变量也不会导致任何变化。而且我不能把这些放在我的 cpp 文件中,因为编译器认为这些值不存在
  • @Yuma:这是一个单独的问题。您正在尝试测量不到一个时钟滴答声的东西。
  • @Yuma 老实说,按照这样的写法,进行 clock 测量将花费更长的时间,而不是执行被测量的实际 eval。所以无论如何你的数字都会非常不准确。
  • @Yuma:您是否进行了我的回答中列出的更改?
  • @Yuma 我不认为你调试这个,实际上确保你的操作员甚至被调用
【解决方案2】:

您设置全局变量的方式似乎存在错误。 (NPE 的回答涵盖了这一点。)

但是,要记住的另一件事是,您正在尝试衡量单个比较的性能。这取决于T 是什么,但对于大多数简单类型,这将是一到两条 CPU 指令,这太小了,无法用这样的技术准确测量。

使用采样分析器会好得多。使用您这里的代码,您的检测比正在完成的工作要昂贵得多,这使得分析数据毫无用处。

【讨论】:

  • 这只是一个例子。我也在我的交换/交换功能中使用了它。即使在交换一个巨大的数组时,时钟滴答也不会变成零。
  • 如果您在std::vector 上使用std::swap,则数组大小无关紧要;交换操作只是交换几个指针(可能是几十个操作码)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 2014-01-08
相关资源
最近更新 更多