配置文件的实现
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 了解更多信息。
并不是说我认为它会有很大帮助,但它是至少可以尝试的替代方法。
如果您知道您检查的值的所有用例,就可以解决这个问题。例如,如果您已经阅读了您的配置文件并且 module1
是 true
- 您做一件事,如果它是 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 种情况(true
和 false
)预定义了行为,并且在启动时解析配置文件期间只创建其中一种的对象。这是 java-like
代码,但当然你可以使用函数指针、std::function
和其他抽象来代替基 class,但是,我认为基 class-option 具有更大的灵活性.
我正在用 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 了解更多信息。
并不是说我认为它会有很大帮助,但它是至少可以尝试的替代方法。
如果您知道您检查的值的所有用例,就可以解决这个问题。例如,如果您已经阅读了您的配置文件并且 module1
是 true
- 您做一件事,如果它是 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 种情况(true
和 false
)预定义了行为,并且在启动时解析配置文件期间只创建其中一种的对象。这是 java-like
代码,但当然你可以使用函数指针、std::function
和其他抽象来代替基 class,但是,我认为基 class-option 具有更大的灵活性.