代码之家  ›  专栏  ›  技术社区  ›  Commodore Yournero

从文件读取矢量的最快方法

c++
  •  1
  • Commodore Yournero  · 技术社区  · 7 年前

    我有3个向量,每个向量正好有256^3~1600万个元素,我想将它们存储在一个文件中并尽可能快地读取。我只关心读取性能,内存中数据的表示可以是任意的。

    我已经研究了一些序列化技术以及使用ofstream在文件中写入/读取普通数字,但是我想知道是否有更直接和更快的方法。

    (我对C++及其概念很陌生)

    1 回复  |  直到 7 年前
        1
  •  1
  •   The Quantum Physicist    7 年前

    假设Windows和Android系统都是Little Endian,这在ARM和x86/x64 CPU中很常见,您可以执行以下操作。

    首先:确定具有特定大小的类型,因此可以是double、64位、32位浮点、uint64/32/16或int64/32/16。不要使用像这样的东西 int 或 long 以确定数据类型。

    第二步:使用以下方法写入二进制数据:

    std::vector<uint64_t> myVec;
    std::ofstream f("outputFile.bin", std::ios::binary);
    f.write(reinterpret_cast<char*>(myVec.data()), myVec.size()*sizeof(uint64_t));
    f.close();
    

    在这里,您将获取原始数据并将其二进制格式写入一个文件。

    现在在另一台机器上,确保使用的数据类型相同 数据类型大小和相同的endianness . 如果两者相同,则可以执行以下操作:

    std::vector<uint64_t> myVec(sizeOfTheData);
    std::ifstream f("outputFile.bin", std::ios::binary);
    f.read(reinterpret_cast<char*>(&myVec.front()), myVec.size()*sizeof(uint64_t));
    f.close();
    

    请注意,在读取数据之前,您必须知道数据的大小。

    注意:这个代码我记不住了。我还没有测试过,但应该可以用。

    现在,如果目标系统没有相同的endianness,则必须批量读取数据,翻转endianness,然后将其放入向量中。如何翻转词尾被广泛讨论。 here .

    为了确定系统的结尾,我们讨论了 here .

    对性能的惩罚将与这些系统的不同程度成正比。如果它们都是相同的endianness,并且您选择了相同的数据类型和大小,那么您就很好,并且具有最佳的性能。否则,您将受到一些惩罚,这取决于您必须进行多少转换。这是你能达到的最快速度。

    注释中的注释:如果要传输双精度或浮点型,请确保两个系统都使用IEEE754标准。这是非常常见的使用这些,而不是结束语,但只是为了确保。

    现在,如果这些解决方案不适合您,那么您必须使用适当的序列化库来标准化格式。有些库可以做到这一点,例如 protobuf .