I am looking for fast conversions. I found out that converting with atof is much more faster than using the stringstream like the below tests.

What I look for now is a fast way to convert from double to char*
I have a problem to find this conversion.

char* to double takes 3.1 sec

double Number1;
	char* Num = "8.12";

	for(int i = 0; i < 2000000; i++)
	{			
		Number1 = atof(Num);
	}
	MessageBox::Show("Finish");

std::string to double takes 35 sec

double Number1;
	std::string Num = "8.12";

	for(int i = 0; i < 2000000; i++)
	{			
		stringstream v1(Num);
		v1 >> Number1;
	}
	MessageBox::Show("Finish");

double to std::string takes 51 sec

double Number1 = 8.12;
	std::string Num;

	for(int i = 0; i < 2000000; i++)
	{			
		stringstream v1;
		v1 << Number1;
		Num = v1.str();
	}
	MessageBox::Show("Finish");

Recommended Answers

All 9 Replies

You test may not be entirely accurate, for example in this part of the code:

for (int i = 0; i < 2000000; i++) {			
   stringstream v1(Num);
   v1 >> Number1;
}

Because here you are constructing stringstream 2000000 times, and destroying it 2000000 times, which obviously is going to add to the total amount of time, if you try making it a global or static variable, and just clear the stream every cycle, then hopefully this should speed it up. Like this:

double Number1;
std::string Num = "8.12";
stringstream v1;

for (int i = 0; i < 2000000; i++) {
   v1 << Num;
   v1 >> Number1;
   v1.clear();
}

Yes you are right. When changing that, the test went down from 35 to 20 seconds.
Great to think about these details !

I don't know about C++, but in C you can use the function fcvt .. which I think is faster than sprintf . See here

> What I look for now is a fast way to convert from double to char*
> I have a problem to find this conversion.

a. compile C++ source to generate native code, not IL that is interpreted at run-time.
b. enable optimizations.

with these two, this is what i get:

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <math.h>

#pragma unmanaged   // generate native code
void double_to_string()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 2000000; i++)
  {			
    double Number1 = 8.12;
    static std::string Num;
    static std::stringstream v1;
	  v1 << Number1;
	  v1 >> Num;
  }
  std::clock_t end = std::clock() ;
  std::cout << "double_to_string: "
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

#pragma unmanaged   // generate native code
void string_to_double()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 2000000; i++)
  {			
    double Number1 ;
    static std::string Num = "8.12" ;
    static std::stringstream v1;
	  v1 << Num;
	  v1 >> Number1;
  }
  std::clock_t end = std::clock() ;
  std::cout << "string_to_double: " 
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

#pragma unmanaged   // generate native code
void cstrng_to_double()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 2000000; i++)
  {	
    double Number1 ;
    const char* Num = "8.12";
    Number1 = std::atof(Num);
  }
  std::clock_t end = std::clock() ;
  std::cout << "cstrng_to_double: " 
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

int main( array< System::String^ >^ args )
{
  for( int i=0 ; i<4 ; ++i )
  {
    double_to_string() ;
    string_to_double() ;
    cstrng_to_double() ;
    std::cout << '\n' ;
  }
}

on T2330 @ 1.6 GHz VC++ Express 2008 SP1 with Full Optimization (/Ox)

double_to_string: 0.936
string_to_double: 0.905
cstrng_to_double: 1.357

double_to_string: 0.936
string_to_double: 0.905
cstrng_to_double: 1.342

double_to_string: 0.936
string_to_double: 0.889
cstrng_to_double: 1.326

double_to_string: 0.92
string_to_double: 0.905
cstrng_to_double: 1.342

added later: just saw your thread 'fasted way to read a text file'. the two points above apply to that too.

This is off topic, but I'm curious...

Why did you use msiL implementation with unmanaged code? Why not purely managed or purely unmanaged?

only because the language the OP is using ( MessageBox::Show ) is C++/CLI (not ISO C++).
and purely managed will not give anywhere near native performance.

commented: Good to know. Thanks =) +4

writing a convert function (with construction and destruction of a stringstream each time it is called) would give more maintainable code. even in this case, the performance seems to be acceptable:

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <math.h>

#pragma unmanaged
void double_to_string()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 200000; i++)
  {			
    double Number1 = 8.12;
    static std::string Num ;
    std::ostringstream v1 ;
    v1 << Number1 ;
    Num = v1.str() ;
  }
  std::clock_t end = std::clock() ;
  std::cout << "double_to_string: "
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

#pragma unmanaged  // generate native code
void string_to_double()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 2000000; i++)
  {			
    double Number1 ;
    static std::string Num = "8.12" ;
    std::istringstream v1(Num);
    v1 >> Number1 ;
  }
  std::clock_t end = std::clock() ;
  std::cout << "string_to_double: " 
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

#pragma unmanaged
void cstrng_to_double()
{
  std::clock_t start = std::clock() ;
  for(int i = 0; i < 2000000; i++)
  {	
    double Number1 ;
    const char* Num = "8.12";
    Number1 = std::atof(Num);
  }
  std::clock_t end = std::clock() ;
  std::cout << "cstrng_to_double: " 
    << double( end-start ) / CLOCKS_PER_SEC << '\n' ;
}
#pragma managed

int main( array< System::String^ >^ args )
{
  for( int i=0 ; i<4 ; ++i )
  {
    double_to_string() ;
    string_to_double() ;
    cstrng_to_double() ;
    std::cout << '\n' ;
  }
}
double_to_string: 1.186
string_to_double: 9.921
cstrng_to_double: 1.311

double_to_string: 1.17
string_to_double: 9.921
cstrng_to_double: 1.295

double_to_string: 1.17
string_to_double: 9.906
cstrng_to_double: 1.295

double_to_string: 1.17
string_to_double: 9.921
cstrng_to_double: 1.295

Results of double_to_string() is somewhat off due to a missing zero ...

void double_to_string()
{
std::clock_t start = std::clock() ;
for(int i = 0; i < 2000000; i++)
{

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.