C++ 对数据进行二值化的最佳方法是什么

C++ 对数据进行二值化的最佳方法是什么,c++,data-serialization,C++,Data Serialization,我有一些数据文件被写为tag=value,其中tag是string,value可以是数值、字符串、数组等。我使用这种格式是因为它可读且易于编辑。现在,使用这种格式实例化的每个类都有一个load方法,它读取所需的标记并使用这些标记中的值。我想使数据二进制化以提高加载速度。一种方法是在每个类中都有一个ToBinary(名称无关紧要)方法,该方法读取旧数据并将其写入文件,然后使用新文件实例化对象。这可以脱机完成,仅一次/应用程序。你对此还有其他建议吗?我用C++来做这个。 编辑: 我认为现在最昂贵的部

我有一些数据文件被写为tag=value,其中tag是string,value可以是数值、字符串、数组等。我使用这种格式是因为它可读且易于编辑。现在,使用这种格式实例化的每个类都有一个load方法,它读取所需的标记并使用这些标记中的值。我想使数据二进制化以提高加载速度。一种方法是在每个类中都有一个ToBinary(名称无关紧要)方法,该方法读取旧数据并将其写入文件,然后使用新文件实例化对象。这可以脱机完成,仅一次/应用程序。你对此还有其他建议吗?我用C++来做这个。 编辑:
我认为现在最昂贵的部分是在我第一次读取文件时解析文件,然后搜索我需要的标记,而不是从磁盘读取文件。我可以使用自定义文件系统在一个大文件中包含多个小文件。

我以前没有使用过它,但我确信这是一个很好的开始。

如果您使用的是文件,那么使用二进制数据可能不会显著提高性能,除非您在文件中存储了非常大的数据块(图像、视频…)


但无论如何,您可以使用二进制序列化算法,例如来自的算法。

另一个是来自google的protobuf。虽然不是最快的,但它可以支持不断变化的数据类型,在网络上非常高效,并支持其他语言


Link.

我有一个用于此的序列化基类,其中包含带有小标题的To/From函数,可以在其中嵌入版本处理。我认为这是一个很好的系统,用于需要本地存储的简单数据,并且在大多数情况下是“只读”的

大概是这样的:

class SeralizeMe
{
public:

 virtual bool To(Archive &file)=0;
 virtual bool From(Archive &file)=0;

 virtual bool NeedsSave(void)=0;

};
但是,如果您:

  • 需要经常更改格式
  • 需要选择要加载的数据和要存储的数据
  • 使用大文件,这对保存时的断电特别敏感

如果以上任何一项适用,请使用数据库,FirebirdSQL embedded是一个合适的竞争者。

如果要提高性能,必须使用固定长度字段。解析或加载可变长度字段不会显著提高性能。按文本行读取包括扫描行尾标记。扫描浪费时间

在使用以下任何建议之前,请分析您的代码,以确定性能的基准时间或数字。在每个建议之后执行此操作,因为它将使您能够计算每个优化的性能增量。我的预测是,随着每次优化,增量将变小

我建议首先将文件转换为固定长度的记录,仍然使用文本。根据需要用空格填充字段。因此,知道记录的大小后,可以将读取的数据块到内存中,并将内存视为数组。这将带来显著的改善

此时,您的瓶颈仍然是文件I/O速度(因为文件I/O是由操作系统控制的),以及扫描/转换文本。一些进一步的优化是:将文本转换为数字,最后转换为二进制无论如何,最好将数据文件保存为人类可读的格式。

在降低数据文件的可读性之前,请尝试将应用程序拆分为线程。一个线程处理GUI,另一个线程处理输入,另一个线程处理处理。想法是让处理器总是执行一些代码,而不是等待。在现代平台中,文件I/O可以在CPU处理代码时执行

如果您不关心可移植性,请查看您的平台是否具有DMA功能(DMA或直接内存访问组件允许在不使用处理器或尽量减少处理器使用的情况下进行数据传输)。需要注意的是,许多平台在处理器和DMA之间共享地址和数据总线。因此,一个组件被阻塞或挂起,而另一个组件使用地址和数据总线。所以它可能会有帮助,也可能不会。取决于平台的接线方式

将密钥字段转换为使用数字,即标记。因为标记是数字的,所以它们可以用作跳转表(也可以是switch语句)的索引,或者只是数组的索引

最后,将文件转换为二进制文件。二进制版本应该有两个字段:作为令牌的键和值。将大数据块拖入内存

总结
  • 将大数据块拖拉到 记忆
  • 更改之前的配置文件 建立绩效基准 测量
  • 一次优化一个步骤, 在每次优化之后进行分析
  • 更喜欢将数据文件保存在人工文件中 可读形式
  • 尽量减少对数据文件的更改
  • 将文件转换为使用固定长度 田地
  • 尝试使用线程或多任务 所以应用程序并没有等待
  • 将文本转换为数字标记 (降低人类可读性)
  • 最后将数据转换为二进制文件 度假胜地(人类很难去 读取和调试)

  • 我有两个想法:

    1) 如果标记列表是常量且事先已知,则可以将每个标记转换为一个字节(或字),后跟值的长度(以字节为单位),后跟值有效负载的原始c字符串

    例如,考虑到以下情况:

    Tag1 = "hello World!" // 12 bytes in length (achieved by "strlen(value) * sizeof(char)" )
    Tag2 = "hello canada!"  // 13 bytes in length 
    
    您可以将其转换为字节流:

    0x0001 0x000B // followed by 12 bytes representing the 'value' // 0x0002 0x000C // followed by 13 bytes representing 'value2'
    
    您的程序只需要知道单词头“0x0001”表示Tag1,而头“0x0002”表示Tag2

    如果您事先不知道标记名,您甚至可以通过遵循类似的长度、值结构来进一步抽象标记名

    2) 也许慢一点只是您的文本解析实现?考虑使用一个专用的开源库来做你想做的事情。例如:“”

    属性树是特殊的