我在这里展示了一种使用 unix 函数打开、读取和写入在文本文件上写入整数的真正优化方法。它们也可以在 Windows 上使用,只是给你一些可以使用的警告。此实现仅适用于 32 位整数。
在您的包含文件中:
class FastIntegerWriter
{
private:
const int bufferSize;
int offset;
int file;
char* buffer;
public:
FastIntegerWriter(int bufferSize = 4096);
int Open(const char *filename);
void Close();
virtual ~FastIntegerWriter();
void Flush();
void Writeline(int value);
};
在您的源文件中
#ifdef _MSC_VER
# include <io.h>
# define open _open
# define write _write
# define read _read
# define close _close
#else
# include <unistd.h>
#endif
#include <fcntl.h>
FastIntegerWriter::FastIntegerWriter(int bufferSize) :
bufferSize(bufferSize),
buffer(new char[bufferSize]),
offset(0),
file(0)
{
}
int FastIntegerWriter::Open(const char* filename)
{
this->Close();
if (filename != NULL)
this->file = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
return this->file;
}
void FastIntegerWriter::Close()
{
this->Flush();
if (this->file > 0)
{
close(this->file);
this->file = 0;
}
}
FastIntegerWriter::~FastIntegerWriter()
{
this->Close();
delete[] this->buffer;
}
void FastIntegerWriter::Flush()
{
if (this->offset != 0)
{
write(this->file, this->buffer, this->offset);
this->offset = 0;
}
}
void FastIntegerWriter::Writeline(int value)
{
if (this->offset >= this->bufferSize - 12)
{
this->Flush();
}
// Compute number of required digits
char* output = this->buffer + this->offset;
if (value < 0)
{
if (value == -2147483648)
{
// Special case, the minimum integer does not have a corresponding positive value.
// We use an hard coded string and copy it directly to the buffer.
// (Thanks to Eugene Ryabtsev for the suggestion).
static const char s[] = "-2147483648\n";
for (int i = 0; i < 12; ++i)
output[i] = s[i];
this->offset += 12;
return;
}
*output = '-';
++output;
++this->offset;
value = -value;
}
// Compute number of digits (log base 10(value) + 1)
int digits =
(value >= 1000000000) ? 10 : (value >= 100000000) ? 9 : (value >= 10000000) ? 8 :
(value >= 1000000) ? 7 : (value >= 100000) ? 6 : (value >= 10000) ? 5 :
(value >= 1000) ? 4 : (value >= 100) ? 3 : (value >= 10) ? 2 : 1;
// Convert number to string
output[digits] = '\n';
for (int i = digits - 1; i >= 0; --i)
{
output[i] = value % 10 + '0';
value /= 10;
}
this->offset += digits + 1;
}
我想这将优于所有其他写入 ascii 文件的方法:) 使用 Windows 低级 apis WriteFile 和 ReadFile 可能会获得更高的性能,但这不值得付出努力。
要使用它...
int main()
{
FastIntegerWriter fw;
fw.Open("test.txt");
for (int i = -2000; i < 1000000; ++i)
fw.Writeline(i);
return 0;
}
如果您不指定任何文件,它将使用标准输出(控制台)。