配置文件的实现

Implementation of config file

本文关键字:实现 配置文件      更新时间:2023-10-16

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

Module1=true

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

If(module1) {
    DO_STUFF();
}

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

只有在使用探查器发现瓶颈时才优化代码分支预测应该在这里做它的事情,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;
    ...
}

所以我最终会得到你已经拥有的。

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

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

您可以做的一件事是,如果检查了太多次,就生成一个内联函数。然而,您必须确保函数不应该太大,否则它将是一个更大的瓶颈

对不起,伙计们,我查找时没有发现这个: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.
}

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