CSDN上看到有人问能否实现一个效率较高的max函数,效率接近于宏,于是自动动手写了一个。
由于max宏在判断不同类型时,能够返回大的那个类型(表示范围大),所以只能使用模板来进行返回类型的推导。
在VC8上打开O2或Ox优化选项,测试结果是与宏效率相等。
全部实现如下:
由于max宏在判断不同类型时,能够返回大的那个类型(表示范围大),所以只能使用模板来进行返回类型的推导。
在VC8上打开O2或Ox优化选项,测试结果是与宏效率相等。
全部实现如下:
#include
<
typeinfo
>
#include < cassert >
#include < windows.h >
#include < iostream >
template < class T, class U, bool B >
struct BigType
{
typedef T result;
};
template < class T, class U >
struct BigType < T, U, false >
{
typedef U result;
};
template < class T, class U >
struct Type
{
typedef typename BigType < T, U, ( sizeof (T) > sizeof (U)) > ::result BigType;
};
template < class T >
struct Type < T, double >
{
typedef double BigType;
};
template < class T >
struct Type < double , T >
{
typedef double BigType;
};
template < class T >
struct Type < T, float >
{
typedef float BigType;
};
template < class T >
struct Type < float , T >
{
typedef float BigType;
};
template <>
struct Type < double , float >
{
typedef double BigType;
};
template <>
struct Type < float , double >
{
typedef double BigType;
};
template < class T, class U >
typename Type < T, U > ::BigType MaX ( const T & t, const U & u)
{
typedef typename Type < T, U > ::BigType ResultType;
return ResultType(t > u ? t : u); // 原为return (ResultType)t > u ? t : u;
}
int main ()
{
assert (typeid(MaX( 1 , 2 )) == typeid( int ));
assert (MaX( 1 , 2 ) == 2 );
assert (typeid(MaX( 1 , 2.5 )) == typeid( double ));
assert (MaX( 1 , 2.5 ) == 2.5 );
assert (typeid(MaX( 1 , ( float ) 2.5 )) == typeid( float ));
assert (MaX( 1 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( double ) 2 , ( float ) 2.5 )) == typeid( double ));
assert (MaX(( double ) 2 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( long ) 2 , ( float ) 2.5 )) == typeid( float ));
assert (MaX(( long ) 2 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( long ) 2 , ( short ) 2 )) == typeid( long ));
assert (MaX(( long ) 2 , ( short ) 2 ) == 2 );
assert (typeid(MaX(( float ) 2 , (__int64) 2 )) == typeid( float ));
assert (MaX(( float ) 2 , (__int64) 2 ) == 2 );
assert (std:: string ( " hello " ) < " world " );
assert (typeid(MaX(std:: string ( " hello " ), " world " )) == typeid(std:: string ));
assert (MaX(std:: string ( " hello " ), " world " ) == " world " );
assert (typeid(MaX(std:: string ( " world " ), " hello " )) == typeid(std:: string ));
assert (MaX(std:: string ( " hello " ), " world " ) == " world " );
// 测试数,需定义在循环外,防止编译器优化掉无意义的循环
__int64 test = 0 ;
long start = GetTickCount();
for ( int i = 0 ; i < 1000000000 ; ++ i)
{
test += MaX(i, (__int64)i);
}
// test必须被使用,否则编译器视为无用数据,会被优化掉
std::cout << test << std::endl;
std::cout << (GetTickCount() - start) << std::endl;
test = 0 ;
start = GetTickCount();
for ( int i = 0 ; i < 1000000000 ; ++ i)
{
test += max(i, (__int64)i);
}
std::cout << test << std::endl;
std::cout << (GetTickCount() - start) << std::endl;
return 0 ;
}
#include < cassert >
#include < windows.h >
#include < iostream >
template < class T, class U, bool B >
struct BigType
{
typedef T result;
};
template < class T, class U >
struct BigType < T, U, false >
{
typedef U result;
};
template < class T, class U >
struct Type
{
typedef typename BigType < T, U, ( sizeof (T) > sizeof (U)) > ::result BigType;
};
template < class T >
struct Type < T, double >
{
typedef double BigType;
};
template < class T >
struct Type < double , T >
{
typedef double BigType;
};
template < class T >
struct Type < T, float >
{
typedef float BigType;
};
template < class T >
struct Type < float , T >
{
typedef float BigType;
};
template <>
struct Type < double , float >
{
typedef double BigType;
};
template <>
struct Type < float , double >
{
typedef double BigType;
};
template < class T, class U >
typename Type < T, U > ::BigType MaX ( const T & t, const U & u)
{
typedef typename Type < T, U > ::BigType ResultType;
return ResultType(t > u ? t : u); // 原为return (ResultType)t > u ? t : u;
}
int main ()
{
assert (typeid(MaX( 1 , 2 )) == typeid( int ));
assert (MaX( 1 , 2 ) == 2 );
assert (typeid(MaX( 1 , 2.5 )) == typeid( double ));
assert (MaX( 1 , 2.5 ) == 2.5 );
assert (typeid(MaX( 1 , ( float ) 2.5 )) == typeid( float ));
assert (MaX( 1 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( double ) 2 , ( float ) 2.5 )) == typeid( double ));
assert (MaX(( double ) 2 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( long ) 2 , ( float ) 2.5 )) == typeid( float ));
assert (MaX(( long ) 2 , ( float ) 2.5 ) == 2.5 );
assert (typeid(MaX(( long ) 2 , ( short ) 2 )) == typeid( long ));
assert (MaX(( long ) 2 , ( short ) 2 ) == 2 );
assert (typeid(MaX(( float ) 2 , (__int64) 2 )) == typeid( float ));
assert (MaX(( float ) 2 , (__int64) 2 ) == 2 );
assert (std:: string ( " hello " ) < " world " );
assert (typeid(MaX(std:: string ( " hello " ), " world " )) == typeid(std:: string ));
assert (MaX(std:: string ( " hello " ), " world " ) == " world " );
assert (typeid(MaX(std:: string ( " world " ), " hello " )) == typeid(std:: string ));
assert (MaX(std:: string ( " hello " ), " world " ) == " world " );
// 测试数,需定义在循环外,防止编译器优化掉无意义的循环
__int64 test = 0 ;
long start = GetTickCount();
for ( int i = 0 ; i < 1000000000 ; ++ i)
{
test += MaX(i, (__int64)i);
}
// test必须被使用,否则编译器视为无用数据,会被优化掉
std::cout << test << std::endl;
std::cout << (GetTickCount() - start) << std::endl;
test = 0 ;
start = GetTickCount();
for ( int i = 0 ; i < 1000000000 ; ++ i)
{
test += max(i, (__int64)i);
}
std::cout << test << std::endl;
std::cout << (GetTickCount() - start) << std::endl;
return 0 ;
}