【问题标题】:What overhead is there in performing an identity boost::lexical_cast?执行身份提升::lexical_cast 有什么开销?
【发布时间】:2012-09-11 19:13:36
【问题描述】:

给定一个函数,例如:

template< typename T >
void function1( const T &t )
{
  function2( boost::lexical_cast<std::string>(t) );
}

如果传递给function1 的类型已经是std::string,会产生什么样的开销?

开销是否因我 lexical_cast-ing 的类型而异?

创建一个重载函数来绕过强制转换是多余的吗?例如:

void function1( const std::string &t )
{
  function2( t );
}

template< typename T >
void function1( const T &t )
{
  function1( boost::lexical_cast<std::string>(t) );
}

boost 的版本可能与您的回答有关,据我了解,lexical_cast 已在各个版本中进行了一些优化。

【问题讨论】:

  • 首先,不要做函数模板特化,只是重载
  • @Xeo 好点explained here。已编辑。

标签: c++ boost lexical-cast


【解决方案1】:

由于文档没有提供关于此主题的任何内容,我挖掘了lexical_cast 源代码 (1.51.0) 并发现它对类型进行了一些编译时检查并决定了一个特定的“施法者类”进行转换。如果源和目标相同,这个“施法者类”将简单地返回输入。

来自源代码的伪编码和简化 (boost/lexical_cast.hpp:2268):

template <typename Target, typename Source>
Target lexical_cast(const Source &arg)
{
    static if( is_character_type_to_character_type<Target, src> ||
               is_char_array_to_stdstring<Target, src> ||
               is_same_and_stdstring<Target, src> )
    //         ^-- optimization for std::string to std::string and similar stuff
    {
      return arg;
    }
    else
    {
      /* some complicated stuff */
    }
}

不过,我无法直接看到其他身份转换的任何优化,并且查看通常选择的lexical_cast_do_cast“施法者类”让我头疼。 :(

【讨论】:

  • @Drew:“不过,我无法直接看到其他身份转换的任何优化”——这只是返回参数。
【解决方案2】:

http://www.boost.org/doc/libs/1_51_0/doc/html/boost_lexical_cast/performance.html

考虑一下这个链接,字符串到字符串的速度非常快。

所有测试都以毫秒为单位测量以下代码块的 10000 次迭代的执行速度:

    typedef BOOST_DEDUCED_TYPENAME ::boost::type_traits::ice_or<
            ::boost::detail::is_xchar_to_xchar<Target, src >::value,
            ::boost::detail::is_char_array_to_stdstring<Target, src >::value,
            ::boost::type_traits::ice_and<
                 ::boost::is_same<Target, src >::value,
                 ::boost::detail::is_stdstring<Target >::value
            >::value
    > shall_we_copy_t;

在我们的例子中,shall_we_copy_t::value 为真,因为第三种情况对我们有用(Targetsrc 是相同的类型,Target 的类型是 std::basic_string)。

    typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
        shall_we_copy_t::value,
        ::boost::detail::lexical_cast_copy<src >,
        BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
             shall_we_copy_with_dynamic_check_t::value,
             ::boost::detail::lexical_cast_dynamic_num<Target, src >,
             ::boost::detail::lexical_cast_do_cast<Target, src >
        >::type
    >::type caster_type;

由于shall_we_copy_t::value 为真,我们的 caster_type 将为lexical_cast_copy

return caster_type::lexical_cast_impl(arg);

那么,就叫lexical_cast_copy::lexical_cast_impl,很简单

    template <typename Source>
    struct lexical_cast_copy
    {
        static inline Source lexical_cast_impl(const Source &arg)
        {
            return arg;
        }
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 2021-09-07
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 2015-05-04
    相关资源
    最近更新 更多