为什么我的简单cpp-netlib程序需要这么长时间才能编译
Why does my simple cpp-netlib program take so long to compile?
我最近开始学习cpp-netlib,并正在测试netlib的一个示例程序
#include <boost/network/protocol/http/client.hpp>
#include <iostream>
int main()
{
using namespace boost::network;
http::client client;
http::client::request request("http://www.boost.org");
request << header("Connection", "close");
http::client::response response = client.get(request);
std::cout << body(response) << std::endl;
return 0;
}
经过几个小时的研究,我发现编译程序所需的正确命令是
clang++ -std=c++11 -I /usr/local/Cellar/openssl/1.0.2e/include test.cpp -L /usr/local/Cellar/openssl/1.0.2e/lib -lboost_system-mt -lboost_thread-mt -lcppnetlib-client-connections -lcppnetlib-uri -lcppnetlib-server-parsers -lssl -lcrypto
这里有一个链接,指向我发布的一个旧问题,详细介绍了我是如何找到这个程序在使用HTTP客户端主体时编译带有Boost Mac OSX seg错误的cpp-Netlib所需的一切的
我发现编译大约需要15秒,我想知道是否有办法加快这个过程?编译这些代码真的这么慢吗?或者链接器需要大量时间才能获得所有这些库?如果是,我能加快速度吗?
我似乎记得cpp-netlib使用Spirit Qi语法进行URL解析,例如
network/uri/accessors.hpp
network/uri/uri.ipp
在这种情况下,减速似乎是
accessors.hpp
中的key_value_sequence
解析器
这些非常重模板,编译需要相当长的时间,仅略微取决于所使用的编译器(根据我的经验,MSVC是最糟糕的)。
您可以阻止包含这些标头。至少只将它们包含在需要的翻译单元(cpp
)中;永远不要让它陷入你的"公共"头依赖关系中。这意味着编译器必须在每次迭代中重新编译这些内容(即使使用预编译的头,成本也可能很高)。
根据您的编译器版本,这些可能会有所帮助:
- 禁用调试信息(-g0)
- 优化大小(-Os)
- 定义BOOstrongPIRIT_USE_PHOENIX_V3(自1.58以来的默认值)
- 将
FUSION_MAX_VECTOR_SIZE
之类的内容定义为较小的数字(默认值:10)
真的,如果你使用支持c++14的clang,我会有兴趣测试一个使用Spirit X3而不是Qi的补丁。
至少替换这个Qi解析器:
#include <boost/spirit/include/qi.hpp>
// ...
namespace details {
template <typename Map>
struct key_value_sequence : spirit::qi::grammar<uri::const_iterator, Map()> {
typedef typename Map::key_type key_type;
typedef typename Map::mapped_type mapped_type;
typedef std::pair<key_type, mapped_type> pair_type;
key_value_sequence() : key_value_sequence::base_type(query) {
query = pair >> *((spirit::qi::lit(';') | '&') >> pair);
pair = key >> -('=' >> value);
key =
spirit::qi::char_("a-zA-Z_") >> *spirit::qi::char_("-+.~a-zA-Z_0-9/%");
value = +spirit::qi::char_("-+.~a-zA-Z_0-9/%");
}
spirit::qi::rule<uri::const_iterator, Map()> query;
spirit::qi::rule<uri::const_iterator, pair_type()> pair;
spirit::qi::rule<uri::const_iterator, key_type()> key;
spirit::qi::rule<uri::const_iterator, mapped_type()> value;
};
} // namespace details
template <class Map>
inline Map &query_map(const uri &uri_, Map &map) {
const uri::string_type range = uri_.query();
details::key_value_sequence<Map> parser;
spirit::qi::parse(boost::begin(range), boost::end(range), parser, map);
return map;
}
使用此X3变体:
#include <boost/spirit/home/x3.hpp>
// ...
namespace details {
namespace kvs_parser {
namespace x3 = boost::spirit::x3;
static auto const key = x3::char_("a-zA-Z_") >> *x3::char_("-+.~a-zA-Z_0-9/%");
static auto const value = +x3::char_("-+.~a-zA-Z_0-9/%");
template <typename Map, typename K = typename Map::key_type, typename V = typename Map::mapped_type, typename Pair = std::pair<K, V> >
static auto const pair = x3::rule<struct kvs_pair, Pair> {}
= key >> -('=' >> value);
template <typename Map>
static auto const query = pair<Map> >> *((x3::lit(';') | '&') >> pair<Map>);
}
} // namespace details
template <class Map>
inline Map &query_map(const uri &uri_, Map &map) {
const uri::string_type range = uri_.query();
spirit::x3::parse(boost::begin(range), boost::end(range), details::kvs_parser::query<Map>, map);
return map;
}
在我的系统上将编译时间从~8s减少到~5s
BIG FAT警告X3代码未经测试(我甚至不知道它的用途,我只是"盲目"地翻译成X3,据我所知)
相关文章:
- 使用Boost Interprocess创建托管共享内存需要很长时间
- SFML RenderWindow打开窗口需要很长时间
- Kafka C++客户端需要很长时间才能收到消息
- 给定使用 C++ 或 C,我如何测量在 linux 下进行线程切换需要多长时间?可能吗?
- asio::read() 需要很长时间,使用 asio::write 没有问题
- 将线程锁定很长时间
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 即使长时间等待,C++线程也不会加入
- 连接() 在连接被拒绝时长时间挂起
- 为什么这段代码需要这么长时间才能用 g++ 编译?
- 如何在长时间运行的方法中等待信号?
- 编译我的C++代码需要很长时间
- Visual Studio C 枚举需要很长时间来编译
- 为什么编译超过100000行std::vector::push_back需要很长时间
- C++程序需要很长时间才能在Mac OSX终端上编译
- 在VS2010中编译需要太长时间
- 为什么我的简单cpp-netlib程序需要这么长时间才能编译
- 使用boost库编译预编译头文件需要很长时间
- 如果包括"assert.h"的每个文件都需要很长的编译时间吗?
- 有时VS2008需要很长时间才能编译