我有一个数字运算程序,其中我想要解决的方程式由不同类的成员函数表示。每个课程都有几个成员变量,它们是方程式的输入。成员变量目前是基本的,如double和int,但为了更好地与GUI集成,我想用托管变量替换原语;即我想使用一个单独的类来保存变量的名称和值,并处理读取和写入其值。我担心代码的性能和可读性。例如,我宁愿看到"自然"查找代码x = y + 2
而不是x.set_value(y.get_value() + 2)
。
我提出了四种不同的方法,并尝试了每种方法花费的时间(下面的代码)。我使用调试版本在MSVC 2013中编译了这个。我在发布模式下得到了无意义的结果,因为我认为我的循环得到了优化。结果似乎很重要;使用原语或直接访问成员变量需要花费一半时间使用getter / setter函数或转换运算符重载。
我的问题是:我是否正确地测试了这些不同的方法?是否有更好的方法来做我想做的事情?感谢。
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
//Class to manage input parameters
struct Parameter {
double _value = 0.0;
double Get_value() const {return _value;}
void Set_value(double value) {_value = value;}
operator double(){return _value;}
void operator=(const double& rhs) {_value = rhs;}
};
int main() {
const size_t NUM_TESTS = 100; //Number of tests to run
const size_t MAX_ITER = 1000000; //Number of iterations to run in each test
const double x = 2.71828; //Variable to read from
double y = 0; //Variable to write to
Parameter test_parameter; //managed variable to read/write from/to
double test_primitive = 0.0; //primitive variable to read/write from/to
size_t t_primitive = 0; //Total time spent on primitive variable (microseconds)
size_t t_managed_cast = 0; //Time spent on managed variable using cast and assignment operators
size_t t_managed_getset = 0; //Time spent on managed variable using getter/setter functions;
size_t t_managed_direct = 0; //Time spent on managed variable using direct access of member var.
for (size_t n = 0; n < NUM_TESTS; ++n) {
//Test using a primitive variable.
auto t0 = high_resolution_clock::now();
for (size_t i = 0; i < MAX_ITER; ++i) {
test_primitive = x;
y = test_primitive;
}
auto t1 = high_resolution_clock::now();
t_primitive += duration_cast<microseconds>(t1-t0).count();
//Test using a managed variable, using cast operator and assignment operator
t0 = high_resolution_clock::now();
for (size_t i = 0; i < MAX_ITER; ++i) {
test_parameter = x;
y = test_parameter;
}
t1 = high_resolution_clock::now();
t_managed_cast += duration_cast<microseconds>(t1-t0).count();
//Test using managed variable, using getter/setter member functions
t0 = high_resolution_clock::now();
for (size_t i = 0; i < MAX_ITER; ++i) {
test_parameter.Set_value(x);
y = test_parameter.Get_value();
}
t1 = high_resolution_clock::now();
t_managed_getset += duration_cast<microseconds>(t1-t0).count();
//Test using managed variable, using direct public access
t0 = high_resolution_clock::now();
for (size_t i = 0; i < MAX_ITER; ++i) {
test_parameter._value = x;
y = test_parameter._value;
}
t1 = high_resolution_clock::now();
t_managed_direct += duration_cast<microseconds>(t1-t0).count();
}
cout << "Average time for primitive (microseconds): " << t_primitive / NUM_TESTS << endl;
cout << "Average time for managed with cast (microseconds): " << t_managed_cast / NUM_TESTS << endl;
cout << "Average time for managed with get/set (microseconds): " << t_managed_getset / NUM_TESTS << endl;
cout << "Average time for managed with direct access (microseconds): " << t_managed_direct / NUM_TESTS << endl;
return 0;
}
答案 0 :(得分:3)
volatile const double x = 2.71828;
volatile double y = 0;
// ^^ VERY IMPORTANT
在那里,我修正了你的基准。
现在再次启用优化,并且只关心启用优化的时序。
答案 1 :(得分:1)
调试版本不会内联这些访问器方法,因此需要更长时间。发布版本不会出现此问题。
尝试使用版本构建,但是制作变量volatile
,我相信这会禁用循环优化。