【发布时间】:2016-12-14 20:30:59
【问题描述】:
我有一个大约 2GB 的原始二进制数据缓冲区,存储在 QByteArray 中,我正在尝试以最快的方式编写它。因为QFile 的速度明显较慢,所以我又开始涉足 C/C++ 风格的写作,我已经有几年没做过了,所以我很生疏。
示例代码:
QFile in("D:/input.las");
in.open(QIODevice::ReadOnly);
QByteArray junk = in.readAll();
in.close();
QFile test1("D:/samplelas/bigset2/out/_test1.las");
test1.open(QIODevice::WriteOnly | QIODevice::Truncate);
if(test1.isOpen())
{
QElapsedTimer t;
t.start();
test1.write(junk);
test1.close();
qDebug("Round\t%'i\tTest QFile\ttook\t%'i", i+1, t.elapsed());
}
FILE* test2 = fopen("D:/_test2.las", "wb");
if(test2)
{
QElapsedTimer t;
t.start();
fwrite(junk.constData(), sizeof(char), junk.size(), test2);
fclose(test2);
qDebug("Round\t%'i\tTest wb\ttook\t%'i", i+1, t.elapsed());
}
FILE* test3 = fopen("D:/_test3.las", "w");
if(test3)
{
QElapsedTimer t;
t.start();
fwrite(junk.constData(), sizeof(char), junk.size(), test3);
fclose(test3);
qDebug("Round\t%'i\tTest w\ttook\t%'i", i+1, t.elapsed());
}
我注意到使用"w" 而不是"wb" 会损坏输出,因为在我的Windows 机器上解释了“换行符”字符(新手错误)。尽管如此,结果还是很有希望的,所以我再次尝试使用“wb”。
我非常吃惊地发现二进制模式慢了 5-10 倍,我不知道为什么。如果有的话,非二进制模式写入应该更快,因为它没有被解释,只是原始数据。
我错过了什么?
Edit1:在 MSVC2010、Windows 7x64 Pro 上使用 Qt 4.8.6 在发布模式下进行测试。
Edit2:添加 QFile 测试用例并澄清问题的解释。
【问题讨论】:
-
如果你翻转代码并先进行非二进制写入会发生什么?还是更快吗?
-
@Phlucious 听起来像磁盘缓存。在第一个文件上它错过了,所以它写得很长,但第二个文件命中了,所以它要短得多。
-
@NathanOliver 我通过独立运行每个测试 10 次(10 次使用“wb”和 10 次使用“w”,在两者之间完全重新启动)重新进行了基准测试,并且二进制文件仍然明显慢 - 27 秒对 5 秒。
-
如果您没有发布一个完整的、独立的测试用例,就无法回答任何问题——最好是一开始就没有损坏的测试用例。您的主要问题很可能是您写入磁盘,这会扭曲结果。改为写入 NUL。此外,
QFile不应比原始写入慢。 -
@KubaOber 使用 QFile::write 写入相同的数据块介于二进制和非二进制 fwrite 方法之间——大约 15 秒。我不知道如何才能比我拥有的更多地简化提供的测试用例......只需注释掉当时没有执行的两个测试。你写给 NUL 的建议没有意义......写到磁盘正是我正在测试的。
标签: c++ qt optimization io