0

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");
6
Contributors
9
Replies
10
Views
9 Years
Discussion Span
Last Post by mitrmkar
0

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();
}
0

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

0

> 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.

0

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

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

1

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.

Votes + Comments
Good to know. Thanks =)
0

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
0

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++)
{

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.