我正在尝试将每个 ‘^’ 字符上的 c++ 字符串解析为向量标记。我一直使用 boost::split 方法,但我现在正在编写性能关键代码,想知道哪一个能提供更好的性能。
例如:
string message = "A^B^C^D";
vector<string> tokens;
boost::split(tokens, message, boost::is_any_of("^"));
对比
boost::char_separator<char> sep("^");
boost::tokenizer<boost::char_separator<char> > tokens(text, sep);
哪一个会提供更好的性能,为什么?
原文由 czchlong 发布,翻译遵循 CC BY-SA 4.0 许可协议
最佳选择取决于几个因素。如果您只需要扫描一次令牌,那么 boost::tokenizer 在运行时和空间性能方面都是一个不错的选择(这些令牌向量可能会占用大量空间,具体取决于输入数据。)
如果您要经常扫描令牌,或者需要一个具有高效随机访问的向量,那么将 boost::split 转换为向量可能是更好的选择。
例如,在令牌长度为 1 字节的“A^B^C^…^Z”输入字符串中,
boost::split/vector<string>
方法将消耗 至少 2*N-1 个字节。使用大多数 STL 实现中存储字符串的方式,您可以计算出它的数量是该数量的 8 倍以上。将这些字符串存储在向量中在内存和时间方面是昂贵的。我在我的机器上进行了一次快速测试,具有 1000 万个令牌的类似模式如下所示:
如果您只是对令牌进行一次性扫描,那么显然令牌生成器会更好。但是,如果您要分解成一个您希望在应用程序的生命周期内重用的结构,那么最好使用一个标记向量。
如果你想走矢量路线,那么我建议不要使用
vector<string>
,而是使用 string::iterators 的矢量。只需分解成一对迭代器并保留一大串令牌以供参考。例如:这个改进版本在同一台服务器上测试需要 1.6s 和 390MB 。而且,最重要的是,这个向量的内存开销与令牌的数量成线性关系——不依赖于令牌的长度,而
std::vector<string>
存储每个令牌。