7

tl;博士

我想QString::number(int)每秒调用很多次。它很慢:似乎每次都分配一个新字符串。尝试setNum在相同的字符串上使用,但仍然没有乐趣。


原始的长问题:

问题

我有一大堆数字(比如整数),我想将它们格式化为文本,然后(可能不会立即)写入文件。天真的方式看起来大约是这样的

QString allData;
foreach(const int & value, values) {
    allData += QString::number(value);
    allData += '\n';
}

在我的机器上处理150000个整数大约需要280 毫秒,这对我来说似乎很多。我想这是因为被调用了 150000 次并且每次都分配新的字符串。当我尝试使用(不分配内存)时,这被证实是问题的根源。QString::numberitoa

可能,但不是 Qt[not-cute]解决方案

QString allData;
char buffer[100];                               // <-------
foreach(const int & value, values) {
    _itoa_s(value, buffer, sizeof(buffer), 10); // <-------
    allData += buffer;
    allData += '\n';
}

对于相同的150000 个整数(大约快4 倍),这大约需要70 毫秒,这对我来说现在是可以接受的(我想我也可以用字符串连接做一些事情,但是让我们把这个问题放在这个问题之外)

我不喜欢我必须使用一些不标准的、可能已弃用、可能不可移植的2函数(并不是说这看起来很丑)。

然后我记得还有一个实例方法:QString::setNum. 我希望我可以使用与 with 相同的模式itoa:只分配一个字符串并每次修改它。

理想但不可行的解决方案

QString allData;
QString number;                       // <-------
foreach(const int & value, values) {
    number.setNum(value);             // <-------
    allData += number;
    allData += '\n';
}

不幸的是,这并没有太大的区别QString::number:再次大约 280 毫秒,好吧,也许是 250 毫秒,仍然太多。

所以,恭喜你到达这里:) 最后......

问题

  1. Qt 专家会建议我什么itoa尽管在其他芬芳的 C++/Qt 代码中有明显的 C 气味,还是闭嘴使用?
  2. 或者我能以某种方式说“来吧,Qstring,把这个数字吃到你身上”
  3. 我想知道为什么setNum没有做到这一点

脚注:

1在实际代码中,我不仅有 150000 个整数,还有 50000 个整数的三元组,我还在'\t'它们之间添加了这些整数。这是与我的实际代码的唯一区别,我想这并不重要:这里我只对QString::numbervs的性能感兴趣itoa

2实际上,我很惊讶 MinGW 也有_itoa_s与 Visual Studio 一样的行为,但我仍然有一些尴尬的感觉,在我优美的 Qt 代码中使用这样一个肮脏的函数会降低它的可移植性。如我错了请纠正我。

4

2 回答 2

5

您可以尝试使用共享相同 QString 接口但更适合性能问题的 QByteArray。我使用以下代码获得 36 毫秒(qt 5.2 clang)与您原来的 57 毫秒(在我的机器上):

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';
}
于 2014-05-03T12:35:23.873 回答
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
于 2014-05-03T12:52:46.227 回答