使用临时对象有性能优势吗?

时间:2012-10-09 08:17:49

标签: c++ boost c++11 boost-asio

我正在审核Boost网站上的HTTP Server 3示例。 connection类中有以下代码:

boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(request_, buffer_.data(), buffer_.data() + bytes_transferred);

其中parse声明为

template <typename InputIterator>
boost::tuple<boost::tribool, InputIterator> parse(request& req, InputIterator begin, InputIterator end)

我认为目标是将tribool的返回值复制到本地变量。但是,如果可以编写类似

的内容,那么通过临时对象(boost::tie)执行此操作的重点是什么
boost::tuple<boost::tribool, char*> result = request_parser_.parse(request_, buffer_.data(), buffer_.data() + bytes_transferred);
// Our tribool is available via result.get<0>();

4 个答案:

答案 0 :(得分:9)

好处不是性能,而是实用性和可读性:因为您对parse返回的第二个对象不感兴趣,所以没有必要保留它。最好完全忽略它,只获得你真正感兴趣的结果,即tribool。以下使用result的代码将更加清晰。

实际上,当一个函数返回多个数据时,通常有用(就可读性而言)将其“拆分”以分别获取各个元素。例如,考虑std::set<T>::insert,它返回元素的迭代器以及指示它是否是新插入的布尔值。您觉得以下哪些代码更清晰:

std::set<int> s;
std::pair<std::set<int>::iterator, bool> res = s.insert(42);

if (res.second)
{
    doSomething(res.first);
}

VS

std::set<int> s;
std::set<int>::iterator itInsertedElement;
bool isNewlyInserted;

tie(itInsertedElement, isNewlyInserted) = s.insert(42);

if (isNewlyInserted)
{
    doSomething(itInsertedElement);
}

在我看来,后者更容易阅读。

答案 1 :(得分:3)

我认为他们主要是为了方便而使用tie。如果您不需要InputIterator,只需要tribool值,为什么要创建命名变量?

此:

boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(request_, buffer_.data(), buffer_.data() + bytes_transferred);

成为这个:

boost::tuple<boost::tribool, char*> results = request_parser_.parse(request_, buffer_.data(), buffer_.data() + bytes_transferred);
boost::tribool result = boost::get<0>(results); // or you can use boost::get<0>(results) everywhere you use it.

你的筹码完全无用results

boost:tie返回的临时值可能会被编译器优化,因此不应该有任何内存开销。

答案 2 :(得分:2)

我认为这只是一个语义考虑因素。

  1. 结果的第二个元素被明确忽略,更明显的是尾随.get<0>()
  2. result变量仅与有用的部分绑定,不需要其他变量。
  3. 此处的性能不应受到影响,因为编译器会将其视为:

     boost::tuple<boost::tribool, char*> __tmp = request_parser_.parse(/**/);
    
     boost::trilbool result;
     boost::tie(result, boost::tuples::ignore) = __tmp;
    

    然后优化器会尽可能地消除这种情况并尽可能减少这种情况。

答案 3 :(得分:0)

我怀疑是否存在任何可衡量的性能差异(当然不能与IO成本相比),但简单地引用result而不是使用get<0>()将其从元组中删除会更方便。