配置文件的实现

Implementation of config file

我正在用 C++ 开发一个应用程序,它需要一个在启动时读取和解释的配置文件。它将包含以下内容:

Module1=true

现在,我最初的计划是将其全部存储在变量中并简单地

If(module1) {
    DO_STUFF();
}

然而,这似乎很浪费,因为它会不断检查一个永远不会改变的值。有什么想法吗?

布尔检查在性能方面没有问题,除非您开始执行它数百万或数十亿次。也许你可以开始合并属于 module1 的代码,但除此之外你必须像现在一样检查它

这真的不是问题。如果您的程序要求 Module1 应该为真,那么让它检查该值并继续。它不会影响你的表现,除非它被检查太多次。

您可以做的一件事是,如果它被检查的次数太多,则创建一个内联函数。但是,你必须确保函数不能太大,否则会成为更大的瓶颈

优化代码,仅当您发现性能分析器的瓶颈时。 分支预测 应该在这里做它的事情,module1永远不会改变,所以如果你在循环中调用它,甚至,那里不应该 是明显的性能损失。

如果想做实验,可以分支一次,做一个指针指向正确的函数:

using func_ptr = void (*)();
func_ptr p = [](){};

if(module1)
    p = DO_STUFF;

while(...)
    p();

但这只是要分析的东西,看看程序集...

还有一些较慢但舒适的方式来存储配置,例如在具有枚举索引的数组或映射中。如果我要在循环中获得一些价值,我会这样做:

auto module1 = modules[MODULE1];        // array and enumeration
//auto module1 = modules.at("module1"); // map and string

while(...)
{
    if(module1)
        DO_STUFF;

    ...
}

所以我会得到你已经拥有的东西。

抱歉各位,我查的时候没发现: MDSN 所以我在启动时检查了一次布尔值,然后我不再需要检查了,因为只启动了正确的函数。

根据您的程序设置方式以及变量如何改变代码的行为,您可以使用函数指针:

if(Module1 == true)
{
   std::function<void(int)> DoStuff = Module1Stuff;
}

然后:

while(true)
{
    DoStuff(ImportantVariable);
}

请参阅 http://en.cppreference.com/w/cpp/utility/functional/function 了解更多信息。

并不是说我认为它会有很大帮助,但它是至少可以尝试的替代方法。

如果您知道您检查的值的所有用例,就可以解决这个问题。例如,如果您已经阅读了您的配置文件并且 module1true - 您做一件事,如果它是 false - 另一件事。让我们从例子开始:

class ConfigFileWorker {
    public:
        virtual void run() = 0;
};

class WithModule1Worker {
    public:
        void run() final override {
            // do stuff as if your `Module1` is true
        }
};

class WithoutModule1Worker {
    public:
        void run() final override {
            // do stuff as if your `Module1` is false
        }
};

int main() {
    std::unique_ptr<ConfigFileWorker> worker;
    const bool Module1 = read_config_file(file, "Module1");
    if (Module1) { // you check this only once during launch and just use `worker` all the time after
        worker.reset(new WithModule1Worker);
    } else {
        worker.reset(new WithoutModule1Worker);
    }

    // here and after just use the pointer with `run()` - then you will not need to check the variable all the time, you'll just perform action.
}

因此您已经为 2 种情况(truefalse)预定义了行为,并且在启动时解析配置文件期间只创建其中一种的对象。这是 java-like 代码,但当然你可以使用函数指针、std::function 和其他抽象来代替基 class,但是,我认为基 class-option 具有更大的灵活性.