zoukankan      html  css  js  c++  java
  • 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:

    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++ 2010TicksRelative to naiveRelative 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.0TicksRelative to naiveRelative 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.9TicksRelative to naiveRelative 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 = 100000;
    static const size_t R = 7;
    
    void PrintStats(std::vector<double> timings) {
        double fastest = std::numeric_limits<double>::max();
    
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "[";
        for (size_t i = 1 ; i<timings.size()-1 ; ++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 = 1 ; i<timings.size() ; ++i) {
            sum += timings[i];
        }
        double avg = sum / static_cast<double>(timings.size()-1);
    
        sum = 0.0;
        for (size_t i = 1 ; i<timings.size() ; ++i) {
            timings[i] = pow(timings[i]-avg, 2);
            sum += timings[i];
        }
        double var = sum/(timings.size()-2);
        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 >= '0' && *p <= '9') {
            r = (r*10.0) + (*p - '0');
            ++p;
        }
        if (*p == '.') {
            double f = 0.0;
            int n = 0;
            ++p;
            while (*p >= '0' && *p <= '9') {
                f = (f*10.0) + (*p - '0');
                ++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=0 ; i<N ; ++i) {
            std::string y;
            if (i & 1) {
                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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; i<nums.size() ; ++i) {
                    double x = strtod(nums[i].c_str(), 0);
                    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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                for (size_t i=0 ; 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=0 ; r<R ; ++r) {
                ticks start = getticks();
                std::istringstream ss;
                for (size_t i=0 ; 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;
        }
    }
    View Code
  • 相关阅读:
    python Database Poll for SQL SERVER
    SQLAlchemy表操作和增删改查
    flask动态url规则
    flask配置管理
    一个Flask运行分析
    Function Set in OPEN CASCADE
    Happy New Year 2016
    Apply Newton Method to Find Extrema in OPEN CASCADE
    OPEN CASCADE Multiple Variable Function
    OPEN CASCADE Gauss Least Square
  • 原文地址:https://www.cnblogs.com/xpvincent/p/7599757.html
Copyright © 2011-2022 走看看