Listing 3: Tracking down performance problems
//complex.cpp:
complex _Cdecl _FARFUNC operator*(complex _FAR & z1,
complex _FAR & z2)
{
double temp_re = z1.re*z2.re - z1.im*z2.im;
double temp_im = z1.im*z2.re + z1.re*z2.im;
return complex(temp_re, temp_im);
}
double _Cdecl _FARFUNC norm(complex _FAR & z)
{
/*
return z.re*z.re + z.im*z.im;
*/
asm LES_ bx, z
asm fld REAL ES_ [bx]
asm fmul st(0), st(0)
asm fld REAL ES_ [bx+8]
asm fmul st(0), st(0)
asm fadd
RETURN_TOS;
}
inline complex _RTLENTRY conj(complex _FAR & __z)
{
return complex(__z.re, -__z.im);
}
inline complex _RTLENTRY
operator/(complex _FAR & __z1, double __re_val2)
{
return complex(__z1.re/__re_val2,
__z1.im/__re_val2);
}
complex _Cdecl _FARFUNC
operator/(complex _FAR & z1, complex _FAR & z2)
{
return z1 * conj(z2) / norm(z2);
}
//cmplxtst.cpp:
#include <stdio.h>
#include <time.h>
#include <fstream.h>
//#include "complex.h"
class complex {
// This is essentialy Borland's class stripped down
// to support just mult and div.
public:
complex(double __re_val, double __im_val=0);
complex();
friend complex operator* ( const complex &x,
const complex &y );
friend complex operator/ ( const complex &x,
const complex &y );
public:
double im,re;
};
/* Prototypes */
complex plex_div(const complex &a,
const complex &b);
complex plex_mult(const complex &a,
const complex &b);
inline complex::complex(double __re_val,
double __im_val)
{ // this is Borland's
re = __re_val;
im = __im_val;
}
inline complex::complex()
{ // this is Borland's
/* if you want your complex numbers initialized ...
re = im = 0;
*/
}
inline complex operator* ( const complex &x,
const complex &y )
{ // This is mine
return
complex(x.re * y.re - x.im * y.im,
x.re * y.im + x.im * y.re );
}
inline complex operator/ (const complex &a,
const complex &b)
// This is mine
double denom = b.re*b.re + b.im*b.im;
return complex(
(a.re * b.re + a.im * b.im) / denom,
(a.im * b.re - a.re * b.im) / denom );
}
complex plex_div(const complex &a,
const complex &b)
{ // this is yours
complex result;
double denom = b.re*b.re + b.im*b.im;
result.re = (a.re * b.re + a.im * b.im) / denom;
result.im = (a.im * b.re - a.re * b.im) / denom;
return(result);
}
complex plex_mult(const complex &a, const complex &b)
{ // this is yours
complex result;
result.re = (a.re * b.re - a.im * b.im);
result.im = (a.re * b.im + a.im * b.re);
return(result);
}
/* ========================================== */
int main(void)
{
const long ITER = 200000L;
cout << endl
<< "Complex number calc comparison for "
<< ITER << " iterations" << endl;
time_t start_time,end_time,calc_time;
long i;
complex a,b,c;
a = complex(19.45,23.76);
b = complex(-12.44,7.995);
start_time = time(NULL);
/* Do a number of calculations */
c = a*b;
for (i=0; i<ITER; i++)
{
c = a * c;
c = a / c;
}
end_time = time(NULL);
calc_time = end_time-start_time;
cout << "Calc time using overloaded ops: "
<< calc_time << " secs" << endl;
/* ========================================= */
start_time = time(NULL);
c = plex_mult(a,b);
for (i=0; i<ITER; i++)
{
c = plex_mult(a,c);
c = plex_div(a,c);
}
end_time = time(NULL);
calc_time = end_time-start_time;
cout << "Calculation time with user functions: "
<< calc_time << " secs" << endl;
return 0;
}
/* End of File */