folly/Conv.h

folly/Conv.h is a one-stop-shop for converting values across types. Its main features are simplicity of the API (only the names to and toAppend must be memorized), speed (folly is significantly faster, sometimes by an order of magnitude, than comparable APIs), and correctness.

Synopsis


All examples below are assume to have included folly/Conv.h and issued using namespace folly; You will need:

    // To format as text and append to a string, use toAppend.
fbstring str;
toAppend(2.5, &str);
CHECK_EQ(str, "2.5"); // Multiple arguments are okay, too. Just put the pointer to string at the end.
toAppend(" is ", , " point ", , &str);
CHECK_EQ(str, "2.5 is 2 point 5"); // You don't need to use fbstring (although it's much faster for conversions and in general).
std::string stdStr;
toAppend("Pi is about ", 22.0 / , &stdStr);
// In general, just use to<TargetType>(sourceValue). It returns its result by value.
stdStr = to<std::string>("Variadic ", "arguments also accepted."); // to<fbstring> is 2.5x faster than to<std::string> for typical workloads.
str = to<fbstring>("Variadic ", "arguments also accepted.");

Integral-to-integral conversion


Using to<Target>(value) to convert one integral type to another will behave as follows:

  • If the target type can accommodate all possible values of the source value, the value is implicitly converted. No further action is taken. Example:
        short x;
unsigned short y;
...
auto a = to<int>(x); // zero overhead conversion
auto b = to<int>(y); // zero overhead conversion
  • Otherwise, to inserts bounds checks and throws std::range_error if the target type cannot accommodate the source value. Example:
    short x;
unsigned short y;
long z;
...
x = ;
auto a = to<unsigned short>(x); // fine
x = -;
a = to<unsigned short>(x); // THROWS
z = ;
auto b = to<int>(z); // fine
z += ;
b = to<int>(z); // THROWS
auto b = to<unsigned int>(z); // fine

Anything-to-string conversion


As mentioned, there are two primitives for converting anything to string: to and toAppend. They support the same set of source types, literally by definition (to is implemented in terms of toAppend for all types). The call toAppend(value, &str)formats and appends value to str whereas to<StringType>(value) formats value as a StringType and returns the result by value. Currently, the supported StringTypes are std::string and fbstring

Both toAppend and to with a string type as a target support variadic arguments. Each argument is converted in turn. FortoAppend the last argument in a variadic list must be the address of a supported string type (no need to specify the string type as a template argument).

Integral-to-string conversion

Nothing special here - integrals are converted to strings in decimal format, with a '-' prefix for negative values. Example:

    auto a = to<fbstring>();
assert(a == "");
a = to<fbstring>(-);
assert(a == "-456");

The conversion implementation is aggressively optimized. It converts two digits at a time assisted by fixed-size tables. Converting a long to an fbstring is 3.6x faster than using boost::lexical_cast and 2.5x faster than using sprintf even though the latter is used in conjunction with a stack-allocated constant-size buffer.

Note that converting integral types to fbstring has a particular advantage compared to converting to std::string No integral type (<= 64 bits) has more than 20 decimal digits including sign. Since fbstring employs the small string optimization for up to 23 characters, converting an integral to fbstring is guaranteed to not allocate memory, resulting in significant speed and memory locality gains. Benchmarks reveal a 2x gain on a typical workload.

char to string conversion

Although char is technically an integral type, most of the time you want the string representation of 'a' to be "a", not 96 That's why folly/Conv.h handles char as a special case that does the expected thing. Note that signed char and unsigned char are still considered integral types.

Floating point to string conversion

folly/Conv.h uses V8's double conversion routines. They are accurate and fast; on typical workloads, to<fbstring>(doubleValue) is 1.9x faster than sprintf and 5.5x faster than boost::lexical_cast (It is also 1.3x faster than to<std::string>(doubleValue)

const char* to string conversion

For completeness, folly/Conv.h supports const char* including i.e. string literals. The "conversion" consists, of course, of the string itself. Example:

    auto s = to<fbstring>("Hello, world");
assert(s == "Hello, world");

Anything from string conversion (i.e. parsing)


folly/Conv.h includes three kinds of parsing routines:

  • to<Type>(const char* begin, const char* end) rigidly converts the range [begin, end) to Type These routines have drastic restrictions (e.g. allow no leading or trailing whitespace) and are intended as an efficient back-end for more tolerant routines.
  • to<Type>(stringy) converts stringy to Type Value stringy may be of type const char*StringPiece,std::string, or fbstring (Technically, the requirement is that stringy implicitly converts to a StringPiece
  • to<Type>(&stringPiece) parses with progress information: given stringPiece of type StringPiece it parses as much as possible from it as type Type and alters stringPiece to remove the munched characters. This is easiest clarified by an example:
    fbstring s = " 1234 angels on a pin";
StringPiece pc(s);
auto x = to<int>(&pc);
assert(x == );
assert(pc == " angels on a pin";

Note how the routine ate the leading space but not the trailing one.

Parsing integral types

Parsing integral types is unremarkable - decimal format is expected, optional '+' or '-' sign for signed types, but no optional '+' is allowed for unsigned types. The one remarkable element is speed - parsing typical long values is 6x faster than sscanffolly/Conv.h uses aggressive loop unrolling and table-assisted SIMD-style code arrangement that avoids integral division (slow) and data dependencies across operations (ILP-unfriendly). Example:

    fbstring str = "  12345  ";
assert(to<int>(str) == );
str = " 12345six seven eight";
StringPiece pc(str);
assert(to<int>(&pc) == );
assert(str == "six seven eight");

Parsing floating-point types

folly/Conv.h uses, again, V8's double-conversion routines as back-end. The speed is 3x faster than sscanf and 1.7x faster than in-home routines such as parse<double> But the more important detail is accuracy - even if you do code a routine that works faster than to<double> chances are it is incorrect and will fail in a variety of corner cases. Using to<double> is strongly recommended.

Note that if the string "NaN" (with any capitalization) is passed to to<double> then NaN is returned, which can be tested for as follows:

    fbstring str = "nan"; // "NaN", "NAN", etc.
double d = to<double>(str);
if (std::isnan(d)) {
// string was a valid representation of the double value NaN
}

Note that passing "-NaN" (with any capitalization) to to<double> also returns NaN.

Note that if the strings "inf" or "infinity" (with any capitalization) are passed to to<double> then infinity is returned, which can be tested for as follows:

    fbstring str = "inf"; // "Inf", "INF", "infinity", "Infinity", etc.
double d = to<double>(str);
if (std::isinf(d)) {
// string was a valid representation of one of the double values +Infinity
// or -Infinity
}

Note that passing "-inf" or "-infinity" (with any capitalization) to to<double> returns -infinity rather than +infinity. The sign of the infinity can be tested for as follows:

    fbstring str = "-inf"; // or "inf", "-Infinity", "+Infinity", etc.
double d = to<double>(str);
if (d == std::numeric_limits<double>::infinity()) {
// string was a valid representation of the double value +Infinity
} else if (d == -std::numeric_limits<double>::infinity()) {
// string was a valid representation of the double value -Infinity
}

Note that if an unparseable string is passed to to<double> then an exception is thrown, rather than NaN being returned. This can be tested for as follows:

    fbstring str = "not-a-double"; // Or "1.1.1", "", "$500.00", etc.
double d;
try {
d = to<double>(str);
} catch (const std::range_error &) {
// string could not be parsed
}

Note that the empty string ("") is an unparseable value, and will cause to<double> to throw an exception.

Non-throwing interfaces

tryTo<T> is the non-throwing variant of to<T>. It returns an Expected<T, ConversionCode>. You can think of Expected as like an Optional<T>, but if the conversion failed, Expected stores an error code instead of a T.

tryTo<T> has similar performance as to<T> when the conversion is successful. On the error path, you can expect tryTo<T>to be roughly three orders of magnitude faster than the throwing to<T> and to completely avoid any lock contention arising from stack unwinding.

Here is how to use non-throwing conversions:

    auto t1 = tryTo<int>(str);
if (t1.hasValue()) {
use(t1.value());
}

Expected has a composability feature to make the above pattern simpler.

    tryTo<int>(str).then([](int i) { use(i); });

Conv的更多相关文章

  1. matlab中的卷积——filter,conv之间的区别

    %Matlab提供了计算线性卷积和两个多项式相乘的函数conv,语法格式w=conv(u,v),其中u和v分别是有限长度序列向量,w是u和v的卷积结果序列向量. %如果向量u和v的长度分别为N和M,则 ...

  2. mysql的conv的用法

    这次的ctf比赛用到这个函数,这里记录一下 题目禁了ascii , ord 那就使用conv 这个函数是用来将字符转换进制的,例如将a转成ASCII码(换个说法就是将16进制的a换成10进制) 那就直 ...

  3. (原)caffe中的conv

    转载请注明出处: https://www.cnblogs.com/darkknightzh/p/10486686.html conv总体调用流程如下图所示: 说明:带o的为输出,如Wo代表输出宽度:带 ...

  4. 深度学习卷积网络中反卷积/转置卷积的理解 transposed conv/deconv

    搞明白了卷积网络中所谓deconv到底是个什么东西后,不写下来怕又忘记,根据参考资料,加上我自己的理解,记录在这篇博客里. 先来规范表达 为了方便理解,本文出现的举例情况都是2D矩阵卷积,卷积输入和核 ...

  5. [转载] Conv Nets: A Modular Perspective

    原文地址:http://colah.github.io/posts/2014-07-Conv-Nets-Modular/ Conv Nets: A Modular Perspective Posted ...

  6. MATLAB卷积运算(conv、conv2、convn)解释

    1 conv(向量卷积运算) 所谓两个向量卷积,说白了就是多项式乘法.比如:p=[1 2 3],q=[1 1]是两个向量,p和q的卷积如下:把p的元素作为一个多项式的系数,多项式按升幂(或降幂)排列, ...

  7. boost-字符编码转换:使用conv

    Windows下的字符集转换可以使用WideCharToMultiByte/ MultiByteToWideChar,Linux下字符集转换可以使用iconv()函数,下面为使用boost的conv来 ...

  8. tensorflow 之常见模块conv,bn...实现

    使用tensorflow时,会发现tf.nn,tf.layers, tf.contrib模块有很多功能是重复的,尤其是卷积操作,在使用的时候,我们可以根据需要现在不同的模块.但有些时候可以一起混用. ...

  9. MySQL中特有的函数CONV函数

    CONV函数:用于对数字进行转换,比如将十进制的数字转化成二进制,参数格式convert(N,frombse,tobase) 将数字N从frombase进制转化成tobase进制,并且以字符串的格式返 ...

随机推荐

  1. Maximum Depth of Binary Tree,求树的最大深度

    算法分析:求树的最小最大深度时候,都有两种方法,第一种是递归思想.树最大最小深度,即为它的子树的最大最小深度+1,是动态规划的思想.还有一种方法是层序遍历树,只不过求最小深度时,找到第一个叶子节点就可 ...

  2. Android静态变量的生命周期

    Android是用Java开发,其静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的时候分配内存的,并且存在于方法区.当类 被卸载的时候,静态变量被销毁.在PC机的客户端程序中, ...

  3. Java回顾之JDBC

    这篇文章里,我们来讨论一些和JDBC相关的话题. 概述 尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的 ...

  4. Android之网络图片加载的5种基本方式

    学了这么久,最近有空把自己用到过的网络加载图片的方式总结了出来,与大家共享,希望对你们有帮助. 此博客包含Android 5种基本的加载网络图片方式,包括普通加载HttpURLConnection.H ...

  5. Leetcode 12

    //日积月累,水滴石穿class Solution { public: string longestCommonPrefix(vector<string>& strs) { if ...

  6. 【hive】关于用户留存率的计算

    首先用户留存率一般是面向新增用户的概念,是指某一天注册后的几天还是否活跃,是以每天为单位进行计算的.一般收到的需求都是一个时间段内的新增用户的几天留存 (1)找到这个时间段内的新增用户(也可能含有地区 ...

  7. 解决Jenkins权限配置错误,导致登录时出现没有Overall/read权限

    问题 由于初次接触jenkins,于是在搭建好jenkins以后,想要对用户进行管理,于是乎开始在系统管理->configure Global Security里设置用户的权限. 在启用安全-& ...

  8. Beta发布

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2408] 视频展示 链接[https://www.cnblogs.com/erc ...

  9. 浏览器的get请求和post请求的区别

    GET 请求和 POST 请求: 1). 使用GET方式传递参数: ①. 在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为             ...

  10. vue.js 源代码学习笔记 ----- codegenEvents.js

    /* @flow */ const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/ const simplePathRE = / ...