当有嵌套循环时,我应该如何决定应该嵌套哪个循环?

When there are nested loops, how should I decide which loop should be nested?

我遇到了一些具有嵌套循环的代码:有一个测量文件列表,其中包含一个测量列表。必须将每个测量值与参考测量值列表进行比较以进行一些检查。

这是一个简单的例子。


class Measurement {
public:
    bool operator==(const Measurement& other) { return isEqual(other); }

private:
    bool isEqual(const Measurement& other) const;

    /* some private fields */
};

class MeasurementFile
{
public:
    std::vector<Measurement> measurements;
};

int main()
{
    std::vector<Measurement> referenceMeasurements = createReferenceMeasurements();
    std::vector<MeasurementFile> files = createMeasurementFiles();

    for (auto & singleFile : files) {
         for (auto & singleMeasurement : singleFile.measurements) {
              for (auto & reference : referenceMeasurements) {
                   if (reference == singleMeasurement) {
                        doSomething(singleMeasurement);
                   }
              }
         }
    }
    return 0;
}

main也可以这样写:

int main()
{
    std::vector<Measurement> referenceMeasurements = createReferenceMeasurements();
    std::vector<MeasurementFile> files = createMeasurementFiles();

    for (auto & reference: referenceMeasurements) {
         for (auto & singleFile : files) {
              for (auto & singleMeasurement : singleFile.measurements) {
                   if (reference == singleMeasurement) {
                        doSomething(singleMeasurement);
                   }
              }
         }
    }
    return 0;
}

所以我的问题是:在上述两个解决方案之间,哪个是最好的(如果有的话)?这只是一个偏好问题吗?

通常,循环顺序基于访问频率和顺序。你是对的,它可以用任何一种方式编写,但实际上第一个选项会更好,你会从内存中加载更少,并且有更好的缓存重用。

auto & 的使用将明确告诉编译器不要复制(您的原始文件没有 &;如果没有它,您将多次重新创建 singleFile 对象结束,不需要。第一个选项显着减少了这一点。话虽这么说,第一个选项仍然可以更好地重用,尽可能重用 singleFile