我有一些程序需要加载的数据我想快点装。
我想有三种方法可以加载它。
将数据写入JSON或XML并解析数据。
将数据序列化为特定的二进制格式并取消序列化。
将数据写入c文件并编译,将数据存储到.so
,使用dlopen
加载共享对象。
第三条路是个好主意吗?
或者,加载持久数据的快速方法是什么?
背景信息:
数据从何而来?
使用程序的用户创建数据。
可以将数据视为配置,程序是固定的,但数据是灵活的。
你的程序只读取数据吗?
不,程序使用它,处理它,也许显示它。。。
您多久更改一次数据?
基本上只有一次,但我认为这无关紧要我只希望它在程序运行期间每次都能快速加载。
你能在程序所在的同一台机器上准备数据吗
跑步?
不,目标机器非常慢…在我使用交叉编译器(ARM)的情况下。
更多背景信息:
我有一个非常低规格的ARM板,希望我的程序加载配置数据尽快所以我想把解析的时间移到数据准备阶段我不关心可移植性或复杂性。只需要速度。
最佳答案
只需要速度。
在我当前的项目中,我有一个非常奇怪的构建设置。
我现在有100个配置文件*.c,只有一个导出结构我使用gcc编译器图书馆看起来是这样的:
// config.h
struct config_s {
char name[24];
bool is_debug_enable;
char some_data[24];
char some_encryption_key[24];
/* etc. */
}
const struct config_s *config_get(void);
// config.c
const struct config_s *config_get(void) {
extern const struct config_s _config_instatation;
return &_config_instatation;
}
这100多个配置文件的示例如下:
// config_kamil.c
#include <config.h>
const struct config_s _config_instatation = {
.name = "kamil",
.is_debug_enable = true,
.some_data = {0x01, 0x02, 0x03, },
.some_encryption_key = { 0x20, 0x30, 0x40, },
};
链接器在每个配置文件上被调用100次以上,并将其与其余代码库链接编译需要很长时间来链接所有这些,构建配置是一团混乱我有100多个可执行文件用户选择要放置在哪个设备上的配置。
或者,我尝试创建一个
__attribute__((__section__("config")))
并将_config_instatation
放入该部分在.elf文件完成后,我们可以用objcopy
替换该节这很快,只有一个可执行文件这导致了错误:编译器足够聪明,可以优化死代码,而且它优化了很多,并且注入的数据并不总是正确的格式,需要构建一个单独的程序/脚本来编译数据我用了更长的时间去编译,但是更容易,更安全的方法。您声明用户提供了配置根据您的需要(或者更确切地说,如果您的业务计划是要向用户收取费用,如果他想更改配置的话),您可以编译一组静态配置,只向用户提供可执行文件,就像我所做的那样用户只看到机器代码如果他想改变配置,他必须花钱买一个新的可执行文件。
或者,您可以设置一个服务,其工作方式如下:用户将以人/用户可读的格式发布其配置,您的服务将使用解析器和编译器将此配置转换为一个对象文件,并将其与其余代码库链接,并将可执行文件返回给用户我可以想象这样的服务可以在用户计算机上下载和安装(包括编译器和所有依赖项等),但我也可以想象这样的服务是一个基于http web post的服务。
无论如何,生成的数据都嵌入到可执行文件中因此,它们可以被解析/准备/准备为您想要的最可读和最可解析的格式,随时可以使用我认为你不会比那更快缺点是,对于每个配置,都必须经过编译器,对于每个配置,都有一个单独的可执行文件。