连接二进制位大小的字符串
Concatenate binary bit-sized strings
我想向文件中写入一系列二进制字符串,这些字符串的长度用位而不是字节表示。考虑二进制形式的两个字符串s1和s2,它们分别为011和01011。在这种情况下,输出文件的内容必须是:01101011(1字节)。我正试图以最有效的方式做到这一点,因为我有数百万个字符串要连接,总共输出几个GB。
C++无法直接处理位,因为它的目标是成为一个轻层上面的硬件和硬件本身不是面向位的。最起码的在一次操作中可以读取/写入的位数是一个字节(通常为8位)。
此外,如果您需要进行磁盘i/o,最好将数据写入块中,而不是一次写入一个字节。库有一些缓冲,但缓冲得越早,代码就越快(传递数据所涉及的代码就越少)。
一个简单的方法可以是
unsigned char iobuffer[4096];
int bufsz; // how many bytes are present in the buffer
unsigned long long bit_accumulator;
int acc_bits; // how many bits are present in the accumulator
void writeCode(unsigned long long code, int bits) {
bit_accumulator |= code << acc_bits;
acc_bits += bits;
while (acc_bits >= 8) {
iobuffer[bufsz++] = bit_accumulator & 255;
bit_accumulator >>= 8;
acc_bits -= 8;
if (bufsz == sizeof(iobuffer)) {
// Write the buffer to disk
bufsz = 0;
}
}
}
没有最佳的方法来解决你的问题本身。但你可以使用一些技巧来加快速度:
- 尝试使用文件I/O同步标志。由于缓冲和缓存的原因,设置/取消设置可能比其他设置快得多
- 尝试使用体系结构大小的变量,以便它们直接放入寄存器:uint32_t用于32位机器,uint64_t用于64位机器
- "易失性"可能有助于将事物保存在寄存器中
- 对大数据使用指针和引用,复制小数据块(以避免不必要的大数据复制以及对小数据的大量查找和页面触摸)
- 使用文件的mmap进行直接访问,并将输出与架构和硬盘的页面大小对齐(通常为4 KiB=4096字节)
- 尝试减少分支(如"if"、"for"、"while"、"()?:"等指令)并使代码线性化
- 如果这还不够,当情况变得艰难时:使用汇编程序(但我不建议初学者这样做)
我认为在这种情况下,多线程会适得其反,因为可以发出的文件写入有限,而且问题不容易划分为小任务,因为每个任务都需要知道它必须在其他任务之后启动多少位,然后你最终必须将所有结果连接在一起。
我过去使用过以下内容,它可能会有所帮助。。。
FileWriter.h:
#ifndef FILE_WRITER_H
#define FILE_WRITER_H
#include <stdio.h>
class FileWriter
{
public:
FileWriter(const char* pFileName);
virtual ~FileWriter();
void AddBit(int iBit);
private:
FILE* m_pFile;
unsigned char m_iBitSeq;
unsigned char m_iBitSeqLen;
};
#endif
FileWriter.cpp:
#include "FileWriter.h"
#include <limits.h>
FileWriter::FileWriter(const char* pFileName)
{
m_pFile = fopen(pFileName,"wb");
m_iBitSeq = 0;
m_iBitSeqLen = 0;
}
FileWriter::~FileWriter()
{
while (m_iBitSeqLen > 0)
AddBit(0);
fclose(m_pFile);
}
void FileWriter::AddBit(int iBit)
{
m_iBitSeq |= iBit<<CHAR_BIT;
m_iBitSeq >>= 1;
m_iBitSeqLen++;
if (m_iBitSeqLen == CHAR_BIT)
{
fwrite(&m_iBitSeq,1,1,m_pFile);
m_iBitSeqLen = 0;
}
}
您可以通过在将数据写入文件之前积累一定数量的数据来进一步改进它。
相关文章:
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 如何从二进制文件中读取字符串
- 二进制数之和(使用C样式字符串)
- 如何使字符串出现在编译的二进制可执行文件的开头?
- 查找"n"二进制字符串中最长公共子字符串的长度
- 递归二进制搜索与字符串数组
- 如何在C ++中将二进制字符串128位转换为十进制字符串?
- 将位字符串转储到二进制文件的最佳方法是什么
- 如何排列二进制字符串以最小化它们之间的距离
- 字符串的递归二进制搜索-C++
- 如何检查二进制文件中是否存在字符串
- 将二进制字符串/文件内容从 c++ 传递到节点 js
- C++ 将二进制字符串转换为整数或比较 2 个字符串以查找差异数
- C++ 如何以二进制格式表示字符串?
- 将大型二进制字符串写入二进制文件
- 字符串二进制组合学
- 如何使用 tolua++ 将 lua 字符串(二进制)传递给 c++
- 将Matlab生成的字符串二进制转换为浮点
- C++ - 将字符串二进制链转换为整数二进制链
- 将字符串(二进制)转换为整数