【问题标题】:c++ organising variables for computation - speed and readabilityc++ 组织变量进行计算 - 速度和可读性
【发布时间】:2013-03-17 06:35:02
【问题描述】:

我目前正在进行大型数值计算,并且在使用变量(双精度类型)时速度是最重要的。想知道是否有更易读的方法来执行以下操作,或者是否有更好的方法使用结构或提升库。

更新:尽管如此,由于许多变量,我最初的目标是将变量间接组织到某种容器中,同时将变量保持为对象而不是引用/指针。

1) 我将对变量进行大量而冗长的计算,它们按照它们的使用顺序声明并在整个程序中发生变化

2)当我决定编辑代码时,可以随时将变量添加到程序中(非常频繁)

3) 组织变量(到指针容器或其他容器中)对于轻松使用这些对象很重要 - 例如,当我使用一段时间后写入文件所有这些对象

我想改为创建一个类来创建一个类型(所有变量对象都是 double 类型)并自动添加到指针向量中 - 作为一个附带问题,这是否有点矫枉过正

我有很多变量像这样进行各种计算(这恰好需要时间):

double varName1 = someValue;
double varName2 = someValue;
double varName3 = someValue;
...
double varNameN = someValue;
...
SOME_COMPUTATION HERE

这是我认为每个变量的可读性最明显的方法。为了存储集合以备将来可能的输出,我将所有内容都放入一个容器中,并为每个元素设置了一个引用变量,如下所示

std::vector<double> store;
...
ADD VALUES TO VECTOR
...
double& varName1 = store[0];
double& varName2 = store[1];
...

但是,当我执行上述方法时,使用引用 (&) 变量的计算成本更高(超时)。然后我决定做相反的事情,存储一个指针向量而不是变量,如果我需要将所有文件写入文件,例如我将使用这个向量并正常对变量执行计算(不是引用)。为此,我想出了以下(丑陋的)方式

std::vector<double*> store;
double create_v(double init, double& d)
{
    store.push_back(&d);
    d = init;
}

double varName1 = create_v(0.05,varName1);

我在徘徊,如果 1) 有一个更好的实现,使用模板/增强的可读性来做同样的事情,或者 2) 像我这样的 C++ 初学者应该知道另一种方法吗? 3)优化我没有考虑最小化上面提到的一些开销(我用 -O2 和 -O3 测试,我使用 g++4.7.2)

【问题讨论】:

  • 你到底想做什么?严格的优化几乎总是需要对环境有特定的了解。我不会肯定地说任何一种方法比其他方法更快,但我会说避免指针和引用可能会有所帮助。此外,为了从缓存局部性中受益,请尝试按照使用顺序声明事物。
  • @Wug 感谢您的评论。为了清楚起见,我更新了上面的内容,其中包含更多信息,新部分以粗体显示

标签: c++ pointers vector containers


【解决方案1】:

g++的4.7.2版本提供了C++11的initializer listssupport。这意味着您可以编写以下代码将所有变量放入vector&lt;double&gt;

vector<double> vec = {varName1, varName2, varName3, ..., varNameN};

这是相当干净的,并且应该为您提供一种将变量组织成向量以用于输出目的的简单方法。这是small demo on ideone

附:您的第三个示例不起作用,因为您正在推回引用,而不是指针。不过,这应该是编译时错误。

【讨论】:

  • 感谢您的意见。根据我的需要,我在上述问题中以粗体提供了更清晰的说明。请注意, varName1 等正在更改值(错过了重要的一点,抱歉 :( )并且对象在使用之前被声明在不同的位置。我认为我需要这样,因为我注意到速度不同。这些计算会很长(天),纯粹用于数值分析
【解决方案2】:

根据您的描述,使用 c 样式的结构可能是可以接受的。您可以利用满足某些限制(Plain Old Data 限制或 POD)的结构的某些行为来进一步简化它们的行为。

POD 结构不能有默认构造函数、析构函数或复制构造函数(编译器提供的默认值除外),也不能有任何虚方法或指针或引用类型的任何成员。您应该能够轻松完成此操作。

一旦你这样做了,你就可以像这样声明这样一个结构:

struct DataSet
{
    double foo;
    double bar[48]; // arrays are legal in POD types
    // snip however many more declarations
};

您将能够将这些结构保存到文件中,例如:

DataSet ds;
// populate and process dataset
ofstream outputfile("somefile.dat", ios_base::out);
outputfile.write((char *) &ds, sizeof(DataSet));

阅读它们会完全按照您的预期工作:与写作相反。只需创建对象并将文件的内容吞入其中即可。使用 DataSet 数组应该同样直观。

【讨论】:

  • 重要的是要注意,但是这种方法提供的版本安全性非常低。考虑添加一个方案来验证您从文件中读取的数据是否是您期望的版本。由于文件的内容实际上是结构的二进制数据,因此重新排序成员或添加/删除成员将通俗地说,搞砸了一切。
猜你喜欢
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多