gpt4 book ai didi

c++ - 提神气缓

转载 作者:可可西里 更新时间:2023-11-01 18:28:33 26 4
gpt4 key购买 nike

我尝试使用 Boost Spirit QI 解析 TPCH 文件。我的实现灵感来自 Spirit QI 的员工示例 (http://www.boost.org/doc/libs/1_52_0/libs/spirit/example/qi/employee.cpp)。数据为 csv 格式,标记用“|”分隔性格。

它可以工作,但速度非常慢(1 GB 需要 20 秒)。

这是我的 lineitem 文件的 qi 语法:

struct lineitem {
int l_orderkey;
int l_partkey;
int l_suppkey;
int l_linenumber;
std::string l_quantity;
std::string l_extendedprice;
std::string l_discount;
std::string l_tax;
std::string l_returnflag;
std::string l_linestatus;
std::string l_shipdate;
std::string l_commitdate;
std::string l_recepitdate;
std::string l_shipinstruct;
std::string l_shipmode;
std::string l_comment;
};

BOOST_FUSION_ADAPT_STRUCT( lineitem,
(int, l_orderkey)
(int, l_partkey)
(int, l_suppkey)
(int, l_linenumber)
(std::string, l_quantity)
(std::string, l_extendedprice)
(std::string, l_discount)
(std::string, l_tax)
(std::string, l_returnflag)
(std::string, l_linestatus)
(std::string, l_shipdate)
(std::string, l_commitdate)
(std::string, l_recepitdate)
(std::string, l_shipinstruct)
(std::string, l_shipmode)
(std::string, l_comment))

vector<lineitem>* lineitems=new vector<lineitem>();

phrase_parse(state->dataPointer,
state->dataEndPointer,
(*(int_ >> "|" >>
int_ >> "|" >>
int_ >> "|" >>
int_ >> "|" >>
+(char_ - '|') >> "|" >>
+(char_ - '|') >> "|" >>
+(char_ - '|') >> "|" >>
+(char_ - '|') >> "|" >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|' >>
+(char_ - '|') >> '|'
) ), space, *lineitems
);

问题似乎是字符解析。它比其他转换慢得多。有没有更好的方法将可变长度标记解析为字符串?

最佳答案

我找到了解决问题的方法。如本文所述Boost Spirit QI grammar slow for parsing delimited strings性能瓶颈是灵气的字符串处理。所有其他数据类型似乎都非常快。

我通过自己处理数据而不是使用灵气处理来避免这个问题。

我的解决方案使用一个辅助类,它为 csv 文件的每个字段提供函数。这些函数将值存储到结构中。字符串存储在 char[] 中。将解析器命中一个换行符,它调用一个将结构添加到结果 vector 的函数。Boost 解析器调用此函数,而不是将值自行存储到 vector 中。

这是我的 TCPH 基准的 region.tbl 文件的代码:

struct region{
int r_regionkey;
char r_name[25];
char r_comment[152];
};

class regionStorage{
public:
regionStorage(vector<region>* regions) :regions(regions), pos(0) {}
void storer_regionkey(int const&i){
currentregion.r_regionkey = i;
}

void storer_name(char const&i){
currentregion.r_name[pos] = i;
pos++;
}

void storer_comment(char const&i){
currentregion.r_comment[pos] = i;
pos++;
}

void resetPos() {
pos = 0;
}

void endOfLine() {
pos = 0;
regions->push_back(currentregion);
}

private:
vector<region>* regions;
region currentregion;
int pos;
};


void parseRegion(){

vector<region> regions;
regionStorage regionstorageObject(&regions);
phrase_parse(dataPointer, /*< start iterator >*/
state->dataEndPointer, /*< end iterator >*/
(*(lexeme[
+(int_[boost::bind(&regionStorage::storer_regionkey, &regionstorageObject, _1)] - '|') >> '|' >>
+(char_[boost::bind(&regionStorage::storer_name, &regionstorageObject, _1)] - '|') >> char_('|')[boost::bind(&regionStorage::resetPos, &regionstorageObject)] >>
+(char_[boost::bind(&regionStorage::storer_comment, &regionstorageObject, _1)] - '|') >> char_('|')[boost::bind(&regionStorage::endOfLine, &regionstorageObject)]
])), space);

cout << regions.size() << endl;
}

这不是一个很好的解决方案,但它可以工作并且速度更快。 (1 GB TCPH 数据需要 2.2 秒,多线程)

关于c++ - 提神气缓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13343874/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com