【发布时间】:2016-12-19 15:22:06
【问题描述】:
我需要解析几个 C 风格的字符串(大约 500k),其中包含由单个空格字符分隔的 4 个浮点数。以下是单个字符串的示例:
“90292 5879 89042.2576 5879”
我需要将这些数字存储在代表两个点的两个结构中。考虑到字符串在解析时可以修改,并且 99.99% 的数字只是无符号整数,那么最快的方法是什么?
以下是我当前的实现:
#include <iostream>
#include <cassert>
#include <chrono>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
using namespace chrono;
struct PointF
{
float x;
float y;
};
void parse_points(char* points, PointF& p1, PointF& p2)
{
auto start = points;
const auto end = start + strlen(points);
// p1.x
start = std::find(start, end, ' ');
assert(start < end);
*start = '\0';
p1.x = static_cast<float>(atof(points));
points = start + 1;
// p1.y
start = std::find(start, end, ' ');
assert(start < end);
*start = '\0';
p1.y = static_cast<float>(atof(points));
points = start + 1;
// p2.x
start = std::find(start, end, ' ');
assert(start < end);
*start = '\0';
p2.x = static_cast<float>(atof(points));
points = start + 1;
// p2.y
start = std::find(start, end, ' ');
assert(start == end);
p2.y = static_cast<float>(atof(points));
}
int main()
{
const auto n = 500000;
char points_str[] = "90292 5879 89042.2576 5879";
PointF p1, p2;
vector<string> data(n);
for (auto& s : data)
s.assign(points_str);
const auto t0 = system_clock::now();
for (auto i = 0; i < n; i++)
parse_points(const_cast<char*>(data[i].c_str()), p1, p2);
const auto t1 = system_clock::now();
const auto elapsed = duration_cast<milliseconds>(t1 - t0).count();
cout << "Elapsed: " << elapsed << " ms" << endl;
cin.get();
return 0;
}
【问题讨论】:
-
我猜
boost::lexical_cast比atof快。 -
@sorosh_sabz 实际上慢了 8 倍以上....
-
解析问题太多了,至少可以先搜索一下。试试这个:"stackoverflow c++ read file space separated float"
-
@Nick thx for note :)
-
这可能高度依赖于所使用的标准库实现的精确性质,因此它可能因平台而异。
标签: c++ string parsing c++11 numbers