c++ stod很慢
C++ Convert String to Double Speed
(There is also a string-to-int performance test.)
A performance benchmark of which method is faster of converting an std::string to a double. The goal is ending up with a double of the value represented in an std::string.
The tested methods are:
- a hand-written naive loop
- atof()
- strtod()
- sscanf()
- boost::lexical_cast<double>()
- boost::spirit::qi::parse()
- std::stringstream
- std::stringstream, reusing the object
Source for the test is at speed-string-to-double.cpp with cycle.h.
The compilers are Microsoft Visual C++ 2010 with _SECURE_SCL disabled, GNU g++ 4.6.0, and LLVM clang++ from Arch.
Tests were run for converting 100000 string containing doubles in the range +/- 99999.99999. The result for the naive loop and atof() are set as the baseline 100% and the other numbers is time spent relative to those. The naive loop wins by a large margin, but Boost.Spirit is the fastest correct implementation.
Windows: MSVC++ 2010
- Compiler: MSVC++ 2010 _SECURE_SCL=0
- Arch: Windows 7 64 bit, 1.60GHz Core i7 Q720, 8 GiB RAM
| VC++ 2010 | Ticks | Relative to naive | Relative to atof() |
|---|---|---|---|
| naive | 4366220 | 1.00 | 0.05 |
| atof() | 82732774 | 18.95 | 1.00 |
| strtod() | 83189198 | 19.05 | 1.01 |
| sscanf() | 168568387 | 38.61 | 2.04 |
| spirit qi | 18932917 | 4.34 | 0.23 |
| lexical_cast | 332374407 | 76.12 | 4.02 |
| stringstream | 361943816 | 82.90 | 4.37 |
| stringstream reused | 240848392 | 55.16 | 2.91 |
Linux: GNU g++ 4.6.0
- Compiler: GNU g++ 4.6.0 -O3
- Arch: VirtualBox on the Windows machine, VT-x, Arch Linux, kernel 2.6.38-ARCH, 1 GiB RAM
| g++ 4.6.0 | Ticks | Relative to naive | Relative to atof() |
|---|---|---|---|
| naive | 4656159 | 1.00 | 0.15 |
| atof() | 30605490 | 6.57 | 1.00 |
| strtod() | 30963926 | 6.65 | 1.01 |
| sscanf() | 56235197 | 12.08 | 1.84 |
| spirit qi | 20731062 | 4.45 | 0.68 |
| lexical_cast | 139521406 | 29.96 | 4.56 |
| stringstream | 184723298 | 39.67 | 6.04 |
| stringstream reused | 100905407 | 21.67 | 3.30 |
Linux: LLVM clang++ 2.9
- Compiler: clang++ 2.9 -O3
- Arch: VirtualBox on the Windows machine, VT-x, Arch Linux, kernel 2.6.38-ARCH, 1 GiB RAM
| clang++ 2.9 | Ticks | Relative to naive | Relative to atof() |
|---|---|---|---|
| naive | 6804881 | 1.00 | 0.22 |
| atof() | 30829865 | 4.53 | 1.00 |
| strtod() | 30871514 | 4.54 | 1.00 |
| sscanf() | 57903993 | 8.51 | 1.88 |
| spirit qi | 24411041 | 3.59 | 0.79 |
| lexical_cast | 149339833 | 21.95 | 4.84 |
| stringstream | 191239066 | 28.10 | 6.20 |
| stringstream reused | 100461405 | 14.76 | 3.26 |
#ifdef _MSC_VER
#define _SECURE_SCL 0
#define _CRT_SECURE_NO_DEPRECATE 1
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#define NOMINMAX
#endif #include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include "cycle.h" static const size_t N = ;
static const size_t R = ; void PrintStats(std::vector<double> timings) {
double fastest = std::numeric_limits<double>::max(); std::cout << std::fixed << std::setprecision();
std::cout << "[";
for (size_t i = ; i<timings.size()- ; ++i) {
fastest = std::min(fastest, timings[i]);
std::cout << timings[i] << ",";
}
std::cout << timings.back();
std::cout << "]"; double sum = 0.0;
for (size_t i = ; i<timings.size() ; ++i) {
sum += timings[i];
}
double avg = sum / static_cast<double>(timings.size()-); sum = 0.0;
for (size_t i = ; i<timings.size() ; ++i) {
timings[i] = pow(timings[i]-avg, );
sum += timings[i];
}
double var = sum/(timings.size()-);
double sdv = sqrt(var); std::cout << " with fastest " << fastest << ", average " << avg << ", stddev " << sdv;
} double naive(const char *p) {
double r = 0.0;
bool neg = false;
if (*p == '-') {
neg = true;
++p;
}
while (*p >= '' && *p <= '') {
r = (r*10.0) + (*p - '');
++p;
}
if (*p == '.') {
double f = 0.0;
int n = ;
++p;
while (*p >= '' && *p <= '') {
f = (f*10.0) + (*p - '');
++p;
++n;
}
r += f / std::pow(10.0, n);
}
if (neg) {
r = -r;
}
return r;
} int main() {
std::vector<std::string> nums;
nums.reserve(N);
for (size_t i= ; i<N ; ++i) {
std::string y;
if (i & ) {
y += '-';
}
y += boost::lexical_cast<std::string>(i);
y += '.';
y += boost::lexical_cast<std::string>(i);
nums.push_back(y);
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = naive(nums[i].c_str());
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "naive: ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = atof(nums[i].c_str());
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "atof(): ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = strtod(nums[i].c_str(), );
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "strtod(): ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = 0.0;
sscanf(nums[i].c_str(), "%lf", &x);
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "sscanf(): ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = boost::lexical_cast<double>(nums[i]);
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "lexical_cast: ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
using boost::spirit::qi::double_;
using boost::spirit::qi::parse;
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
double x = 0.0;
char const *str = nums[i].c_str();
parse(str, &str[nums[i].size()], double_, x);
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "spirit qi: ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
for (size_t i= ; i<nums.size() ; ++i) {
std::istringstream ss(nums[i]);
double x = 0.0;
ss >> x;
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "stringstream: ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
} {
double tsum = 0.0;
std::vector<double> timings;
timings.reserve(R);
for (size_t r= ; r<R ; ++r) {
ticks start = getticks();
std::istringstream ss;
for (size_t i= ; i<nums.size() ; ++i) {
ss.str(nums[i]);
ss.clear();
double x = 0.0;
ss >> x;
tsum += x;
}
ticks end = getticks();
double timed = elapsed(end, start);
timings.push_back(timed);
} std::cout << "stringstream reused: ";
PrintStats(timings);
std::cout << std::endl;
std::cout << tsum << std::endl;
}
}
c++ stod很慢的更多相关文章
- 看到了必须要Mark啊,最全的编程中英文词汇对照汇总(里面有好几个版本的,每个版本从a到d的顺序排列)
java: 第一章: JDK(Java Development Kit) java开发工具包 JVM(Java Virtual Machine) java虚拟机 Javac 编译命令 java ...
- C++11特性中的stoi、stod
本文摘录柳神笔记: 使⽤ stoi . stod 可以将字符串 string 转化为对应的 int 型. double 型变量,这在字符串处理的很 多问题中很有帮助-以下是示例代码和⾮法输⼊的处理 ...
- 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo
有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...
- 再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入
说起采集,其实我是个外行,以前拔过阿里巴巴的客户数据,在我博客的文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 中,介绍过采集用的工具,其实很Low的,分析 ...
- [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office
打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...
- ElasticSearch 5学习(5)——第一个例子(很实用)
想要知道ElasticSearch是如何使用的,最快的方式就是通过一个简单的例子,第一个例子将会包括基本概念如索引.搜索.和聚合等,需求是关于公司管理员工的一些业务. 员工文档索引 业务首先需要存储员 ...
- 11 个很少人知道但很有用的 Linux 命令
Linux命令行吸引了大多数Linux爱好者.一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务.Linux命令和它们的转换对于Linux用户.Shell脚本程序员和管理员来说是最有 ...
- 在网站开发中很有用的8个 jQuery 效果【附源码】
jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuer ...
- Web 开发中很实用的10个效果【附源码下载】
在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...
随机推荐
- select下拉框的数据回显
需求描述:select框,下拉后又很多的选项,选择一个,根绝后台代码做查询,完成之后,页面上的select框还是之前选的那个值 解决思路:select本质就是 value和text一一对应,根据你的s ...
- HTML 转义字符对应表
<%@ tag language="java" pageEncoding="UTF-8" %> <%@ attribute name=&quo ...
- ubuntu 安装Mysql8.0
1. 去官网下载安装包 下载链接:点击打开链接 https://dev.mysql.com/downloads/mysql/ 如果你的系统是32位选择第一个,64位选择第二个 也可以用wget 下载 ...
- solt插槽简单使用实例
在父组件内可以定义方法,变量 等,还可以在父组件中使用呢. 样式可以在子组件里写,也可以在父组件写. 子组件: <template> <div class="admin-u ...
- python 0007
#coding='utf-8'# import re import os def get_list(): list_file=[] for f in os.listdir(): if f.endswi ...
- 查看python脚本的运行pid,让python脚本后台运行
ps -ef | grep Productor.py | grep -v grep # 先测试好 python3 /usr/local/software/ELK/Productor.py # 没问题 ...
- DDD实践:领域事件
要求:修改good表,添加 organization 基础定义 用于引发和调度事件的延迟方法 AddDomainEvent Domain\SeedWork\Entity.cs public abstr ...
- Scala学习教程笔记三之函数式编程、集合操作、模式匹配、类型参数、隐式转换、Actor、
1:Scala和Java的对比: 1.1:Scala中的函数是Java中完全没有的概念.因为Java是完全面向对象的编程语言,没有任何面向过程编程语言的特性,因此Java中的一等公民是类和对象,而且只 ...
- [转] 【Monogdb】MongoDB的日志系统
记得前几天有个小伙伴要查看mongodb的日志,从而排查问题,可能总找不到日志放在何处,今天就系统说一下mongodb的日志系统.mongodb中主要有四种日志.分别是系统日志.Journal日志.o ...
- bzoj2961 共点圆 bzoj 4140
题解: 比较水的一道题 首先我们化简一下式子发现是维护xxo+yyo的最值 显然是用凸包来做 我们可以直接用支持插入删除的凸包 也是nlogn的 因为没有强制在线,我们也可以cdq,考虑前面一半对答案 ...