QString::number(int)
。它非常慢:似乎每次都分配一个新的字符串。试图在相同的字符串上使用setNum
,但仍然没有快乐。原创,长期问题:
我有一大堆数字(例如整数),我想将它们格式化为文本,然后(可能不会立即)写入文件。朴素的方式看起来大概是 1 :
QString allData;
foreach(const int & value, values) {
allData += QString::number(value);
allData += '\n';
}
我机器上的 150000 整数需要 280ms ,这对我来说似乎很重要。我想这是因为QString::number
被调用150000次并且每次都分配新的字符串。当我尝试使用itoa
(不分配内存)时,这被证实是问题的根源。
[not-cute]
解决方案QString allData;
char buffer[100]; // <-------
foreach(const int & value, values) {
_itoa_s(value, buffer, sizeof(buffer), 10); // <-------
allData += buffer;
allData += '\n';
}
对于相同的 150000 整数(约 4x 更快),这需要 70ms ,这对我来说是可接受的(I我认为我也可以使用字符串连接做一些事情,但是让我们把它留在这个问题之外)
但是我不喜欢我必须使用一些不标准的,可能已弃用的,可能不可移植的 2 函数(并不是说这看起来很难看)。< / p>
然后我记得还有一个实例方法:QString::setNum
。我希望我可以使用与itoa
相同的模式:只分配一个字符串并每次修改它。
QString allData;
QString number; // <-------
foreach(const int & value, values) {
number.setNum(value); // <-------
allData += number;
allData += '\n';
}
不幸的是,这与QString::number
没有太大的区别:大约280毫秒,好吧,可能 250毫秒但仍然太多。
所以,恭喜你到达这里:)最后......
itoa
,尽管在其他芳香的C ++ / Qt代码中有明显的C气味?setNum
没有做到这一点?脚注:
1 在实际代码中,我不仅有150000个整数,还有50000个整数三元组,我还在它们之间添加'\t'
。这是我实际代码的唯一区别,我想这并不重要:这里我只对QString::number
vs itoa
的表现感兴趣。
2 实际上,我很惊讶MinGW也有_itoa_s
的行为就像Visual Studio一样,但我仍然有一些尴尬的感觉,在我的抛光Qt中使用这么脏的功能代码降低了它的可移植性。如果我错了,请纠正我。
答案 0 :(得分:5)
您可以尝试使用共享相同QString接口的QByteArray,但更适合性能问题。使用此代码,我获得36 ms(qt 5.2 clang)与原始57 ms(在我的机器上):
QByteArray allDatab;
foreach(const int & value, values) {
allDatab += QByteArray::number(value);
allDatab += '\n';
}
QString result(allDatab);
这个版本和29毫秒(可能确认你对setNum的假设):
QByteArray allDatad;
QByteArray number;
foreach(const int & value, values) {
number.setNum(value);
allDatad += number;
allDatad += '\n';
}
答案 1 :(得分:3)
如何使用STL?
我测试了你的代码(修改循环以简化)
int main() {
stringstream ss;
for(int i=0; i<2000000; ++i) {
ss << i << "\n";
}
}
我获得了
time ./ss_test
real 0m0.146s
user 0m0.139s
sys 0m0.006s
使用Qt版本(在我的机器中)
int main() {
QString allData;
for(int i=0; i<2000000; ++i) {
allData += QString::number(i);
allData += '\n';
}
}
我获得了
time ./qtstring_test
real 0m0.516s
user 0m0.508s
sys 0m0.008s