我是新來的精神和一般的提升。我試圖解析類似如下的VRML文件的一部分:提升精神:緩慢解析優化
point
[
#coordinates written in meters.
-3.425386e-001 -1.681608e-001 0.000000e+000,
-3.425386e-001 -1.642545e-001 0.000000e+000,
-3.425386e-001 -1.603483e-001 0.000000e+000,
註釋與#是可選的開始。
我寫了一個語法,工作正常,但解析過程花了很長時間。我想優化它以更快地運行。我的代碼如下所示:
struct Point
{
double a;
double b;
double c;
Point() : a(0.0), b(0.0), c(0.0){}
};
BOOST_FUSION_ADAPT_STRUCT
(
Point,
(double, a)
(double, b)
(double, c)
)
namespace qi = boost::spirit::qi;
namespace repo = boost::spirit::repository;
template <typename Iterator>
struct PointParser :
public qi::grammar<Iterator, std::vector<Point>(), qi::space_type>
{
PointParser() : PointParser::base_type(start, "PointGrammar")
{
singlePoint = qi::double_>>qi::double_>>qi::double_>>*qi::lit(",");
comment = qi::lit("#")>>*(qi::char_("a-zA-Z.") - qi::eol);
prefix = repo::seek[qi::lexeme[qi::skip[qi::lit("point")>>qi::lit("[")>>*comment]]];
start %= prefix>>qi::repeat[singlePoint];
//BOOST_SPIRIT_DEBUG_NODES((prefix)(comment)(singlePoint)(start));
}
qi::rule<Iterator, Point(), qi::space_type> singlePoint;
qi::rule<Iterator, qi::space_type> comment;
qi::rule<Iterator, qi::space_type> prefix;
qi::rule<Iterator, std::vector<Point>(), qi::space_type> start;
};
,我打算解析部分,位於輸入文本的中間,所以我需要跳過的文字部分,以得到它。我使用repo :: seek來實現它。這是最好的方法嗎?
我以下列方式運行解析器:
std::vector<Point> points;
typedef PointParser<std::string::const_iterator> pointParser;
pointParser g2;
auto start = ch::high_resolution_clock::now();
bool r = phrase_parse(Data.begin(), Data.end(), g2, qi::space, points);
auto end = ch::high_resolution_clock::now();
auto duration = ch::duration_cast<boost::chrono::milliseconds>(end - start).count();
要在輸入文本解析約80K項,大約需要2.5秒,這是我的需求相當緩慢。我的問題是有沒有辦法以更優化的方式編寫解析規則以使其更快(更快)?我怎樣才能改進這個實現呢?
我是新來的精神,所以一些解釋將不勝感激。
如果相同的代碼36毫秒和2.5秒的類似系統(球場)和類似的輸入運行時間之間獲得,我的辦法是使後者沒有優化上。 – rubenvb
對此不確定。我使用VS2013的預編譯版本的boost 1.59庫。你能建議任何優化標誌嗎? –
Boost(.Spirit)非常模板化,預編譯的庫不會讓你放慢速度......你爲什麼認爲*你的代碼編譯得太慢了?精神是在你使用它的時候編譯的,而不是在前面。你需要確保你的代碼的定時發佈版本。 – rubenvb