Skip to content

Instantly share code, notes, and snippets.

@martinmoene
Created October 2, 2012 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinmoene/3818717 to your computer and use it in GitHub Desktop.
Save martinmoene/3818717 to your computer and use it in GitHub Desktop.
Performance test of X& operator=(X?)
/*
* TestOpAssign_Niels_Martin.cpp
*
* Created by Martin on 28 September 2012.
* Adapted by Niels Dekker, 1 Oct 2012
* Copyright 2012 Universiteit Leiden. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
// g++ -O2 -Wall -o TestOpAssign_Niels_Martin.exe TestOpAssign_Niels_Martin.cpp && TestOpAssign_Niels_Martin
// cl -O2 -W3 -nologo -EHsc TestOpAssign_Niels_Martin.cpp && TestOpAssign_Niels_Martin
#include <iomanip>
#include <iostream>
#include <string>
#include <time.h>
#include <cstdlib> // for std::strtol()
template < typename T >
class Conventional
{
public:
typedef T value_type;
typedef Conventional class_type;
Conventional( value_type const x = value_type() ) : v( x ) {}
Conventional( class_type const & other ) : v( other.v ) {}
class_type & operator=( class_type const & other )
{
v = other.v;
return *this;
}
T v;
};
template < typename T >
class CopySwap
{
public:
typedef T value_type;
typedef CopySwap<T> class_type;
CopySwap( value_type const x = value_type() ) : v( x ) {}
CopySwap( class_type const & other ) : v( other.v ) {}
class_type & operator=( class_type other )
{
swap( *this, other );
return *this;
}
friend void swap( class_type & first, class_type & second )
{
using std::swap;
swap( first.v, second.v );
}
T v;
};
template < typename X >
void check_work( X* a, int n, X const & b )
{
for( int i = 0; i < n; ++i )
{
if ( a[i].v != b.v )
{
abort();
}
}
}
template < typename X >
unsigned do_work( X* a, int n, X const & b )
{
const clock_t t1 = clock();
for( int i = 0; i < n; ++i )
{
a[i] = b;
}
const clock_t t2 = clock();
return t2 - t1;
}
inline const std::string to_string( const long x, const int base = 10 )
{
char buf[65];
return _ltoa( x, buf, base );
}
std::string compiler_name()
{
#if defined( _MSC_VER )
return "MS VC " + to_string(_MSC_VER / 100 - 6) + "." + to_string(_MSC_VER % 100) ;
#elif defined( __GNUC__ )
return "GCC " + to_string(__GNUC__) + "." + to_string(__GNUC_MINOR__) + "." + to_string(__GNUC_PATCHLEVEL__) ;
#endif
return "Unknown";
}
int main()
{
std::cout <<
"\nPerformance test of X& operator=(X?)." <<
"\n"
"\nCompiler: " << compiler_name();
const int n = 200000000;
unsigned results[2];
{
Conventional<double>* const a = new Conventional<double>[n];
Conventional<double> b(0.125);
results[0] = do_work( a, n, b );
check_work( a, n, b );
delete [] a; // Oops, no RAII!!!
}
{
CopySwap<double>* const a = new CopySwap<double>[n];
CopySwap<double> b(0.125);
results[1] = do_work( a, n, b );
check_work( a, n, b );
delete [] a; // Oops, code duplication.
}
const double cps = CLOCKS_PER_SEC;
std::cout << std::setprecision(2) <<
"\tConventional: " << results[0] << " clock ticks, " << 1e9 * (results[0]/cps)/n << " ns" <<
"\tCopy-swap: " << results[1] << " clock ticks, " << 1e9 * (results[1]/cps)/n << " ns" <<
std::endl;
return 0; // VC6
}
/*
* end of file
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment