diff --git a/harbour/ChangeLog b/harbour/ChangeLog index e988a06c16..037b75e62f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,18 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-10-03 21:53 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + - harbour/tests/speedtst.prg + + harbour/tests/speedold.prg + * renamed old speed test - I left it because some other xbase compiler + cannot compiple the new one due to not Clipper compatible PP + + + harbour/tests/speedtst.prg + * added new speed test which can also measure mutlithread performance. + When linked with MT HVM version then it can be executed with optional + parameter which causes that each test loop is executed by separate + thread. Please make such tests on different platforms. + 2008-10-03 20:20 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/vm/garbage.c * Use spinlock instead of mutex in OS2 builds - performance test. diff --git a/harbour/tests/speedold.prg b/harbour/tests/speedold.prg new file mode 100644 index 0000000000..279a71184a --- /dev/null +++ b/harbour/tests/speedold.prg @@ -0,0 +1,589 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * a small speed test program + * + * Copyright 2006 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + */ + +#define ARR_LEN 16 +#define N_LOOPS 1000000 + +//#define NO_DBF_TEST +#define NO_KEYBOARD_TEST +#define NO_ASSOC_TEST + +#define REAL_TIME + +#ifdef __CLIP__ + #define ASSOC_ARRAY map() + #undef REAL_TIME +#endif +#ifdef FlagShip + #undef REAL_TIME + #xtranslate seconds() => fs_seconds() +#endif +#ifdef __HARBOUR__ + #include "hbmemory.ch" + #define ASSOC_ARRAY { => } + #undef REAL_TIME +#endif + +#ifdef REAL_TIME + #xtranslate secondscpu([]) => seconds() +#endif +#ifndef EOL + #define EOL hb_OSNewLine() +#endif +#command ? => outstd(EOL) +#command ? => outstd(, EOL) + +#ifdef NO_ASSOC_TEST + #undef ASSOC_ARRAY +#endif + +function main() +#ifndef NO_DBF_TEST +field F_C, F_N, F_D +#endif +memvar M_C, M_N, M_D +local L_C, L_N, L_D +local i, j, t, c, c2, n, d, o, bc, tn, total, totalr, aa,; + a[ARR_LEN], a2[ARR_LEN], a3[ARR_LEN], aDb, cFi1, cFi2 +#ifdef ASSOC_ARRAY + local aAssoc := ASSOC_ARRAY +#endif +private M_C := dtos(date()),; + M_N := 112345.67,; + M_D := date() + +#ifndef __CLIP__ +//#ifdef __HARBOUR__ +// setcancel(.f.) +// altd(0) +//#endif +#endif +#ifdef __CLIP__ + SET MACRO_IN_STRING OFF + //CLEAR SCREEN +#endif +#ifdef FlagShip + FS_SET( "zerobyte", .t. ) + FS_SET( "devel", .f. ) +// FS_SET( "break", 0 ) +// FS_SET( "debug", 0 ) +#endif + +for i:=1 to len(a) + a[i]:=i + a2[i]:=dtos(date())+chr(i%64+32)+chr(i%64+64)+str(i,10) + a3[i]:=stuff(dtos(date()),7,0,".") +next + +#ifdef __HARBOUR__ +if MEMORY( HB_MEM_USEDMAX ) != 0 + ? + ? "Warning !!! Memory statistic enabled." +endif +#endif +? +? "Startup loop to increase CPU clock..." +t:=seconds()+5; while t > seconds(); enddo + +? +? date(), time(), VERSION()+build_mode()+", "+OS() +? "ARR_LEN =", ARR_LEN +? "N_LOOPS =", N_LOOPS + +t:=secondscpu() +for i:=1 to N_LOOPS +next +tn:=secondscpu()-t +? "empty loops overhead =", tn +#ifdef REAL_TIME + ? "real time -> seconds()" +#else + ? "CPU usage -> secondsCPU()" +#endif +? "" + +#ifndef NO_DBF_TEST + +aDb:={ {"F_C", "C", 10, 0},; + {"F_N", "N", 10, 2},; + {"F_D", "D", 8, 0} } + +cFi1:="tst_tmp.dbf" +if file(cFi1) + ferase(cFi1) +endif +dbcreate(cFi1, aDb) +select(1) +use &cFi1 shared +dbappend() +replace F_C with dtos(date()) +replace F_N with 112345.67 +replace F_D with date() +dbcommit() +dbunlock() + +cFi2:="tst_tmp2.dbf" +if file(cFi2) + ferase(cFi2) +endif +dbcreate(cFi2, aDb) +select(2) +use &cFi2 exclusive +dbappend() +replace F_C with dtos(date()) +replace F_N with 112345.67 +replace F_D with date() +dbcommit() +dbunlock() + +#endif + +L_C := dtos(date()) +L_N := 112345.67 +L_D := date() + + +total:=secondscpu() +totalr:=seconds() +t:=secondscpu() +for i:=1 to N_LOOPS + c:=L_C +next +dsp_time( "c:=L_C -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + n:=L_N +next +dsp_time( "n:=L_N -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + d:=L_D +next +dsp_time( "d:=L_D -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + c:=M_C +next +dsp_time( "c:=M_C -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + n:=M_N +next +dsp_time( "n:=M_N -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + d:=M_D +next +dsp_time( "d:=M_D -> ", t, tn) + +#ifndef NO_DBF_TEST +select(1) +t:=secondscpu() +for i:=1 to N_LOOPS + c:=F_C +next +dsp_time( "(sh) c:=F_C -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + n:=F_N +next +dsp_time( "(sh) n:=F_N -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + d:=F_D +next +dsp_time( "(sh) d:=F_D -> ", t, tn) + +select(2) +t:=secondscpu() +for i:=1 to N_LOOPS + c:=F_C +next +dsp_time( "(ex) c:=F_C -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + n:=F_N +next +dsp_time( "(ex) n:=F_N -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + d:=F_D +next +dsp_time( "(ex) d:=F_D -> ", t, tn) +#endif + +o:=errorNew() +t:=secondscpu() +for i:=1 to N_LOOPS + n:=o:GenCode +next +dsp_time( "n:=o:GenCode -> ", t, tn) + +#ifdef __HARBOUR__ +t:=secondscpu() +for i:=1 to N_LOOPS + n:=o[8] +next +dsp_time( "n:=o[8] -> ", t, tn) +#endif + +#ifdef ASSOC_ARRAY +t:=secondscpu() +for i:=1 to N_LOOPS + aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100))]:=i +next +dsp_time( "aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100)]:=i -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + c:=aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100))] +next +dsp_time( "c:=aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100)] -> ", t, tn) +#endif + +#ifndef NO_KEYBOARD_TEST +t:=secondscpu() +for i:=1 to N_LOOPS + inkey() +next +dsp_time( "inkey() -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + nextkey() +next +dsp_time( "nextkey() -> ", t, tn) +#endif + +t:=secondscpu() +for i:=1 to N_LOOPS + round(i/1000,2) +next +dsp_time( "round(i/1000,2) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + str(i/1000) +next +dsp_time( "str(i/1000) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + val(a3[i%ARR_LEN+1]) +next +dsp_time( "val(a3[i%ARR_LEN+1]) -> ", t, tn) + +t:=secondscpu() +j:=date() +for i:=1 to N_LOOPS + dtos(j+i%10000-5000) +next +dsp_time( "dtos(j+i%10000-5000) -> ", t, tn) + +bc:={||i%ARR_LEN} +t:=secondscpu() +for i:=1 to N_LOOPS + eval(bc) +next +dsp_time( "eval({||i%ARR_LEN}) -> ", t, tn) + +bc:={|x|x%ARR_LEN} +t:=secondscpu() +for i:=1 to N_LOOPS + eval(bc,i) +next +dsp_time( "eval({|x|x%ARR_LEN},i) -> ", t, tn) + +bc:={|x|f1(x)} +t:=secondscpu() +for i:=1 to N_LOOPS + eval(bc,i) +next +dsp_time( "eval({|x|f1(x)},i) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + n:=&("f1("+str(i)+")") +next +dsp_time( "&('f1('+str(i)+')') -> ", t, tn) + +bc:=&("{|x|f1(x)}") +t:=secondscpu() +for i:=1 to N_LOOPS + eval(bc,i) +next +dsp_time( "eval([&('{|x|f1(x)}')]) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + j:=valtype(a)+valtype(i) +next +dsp_time( "j := valtype(a)+valtype(i) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + j := str(i%100,2) $ a2[i%ARR_LEN+1] +next +dsp_time( "j := str(i%100,2) $ a2[i%ARR_LEN+1] -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + j := val(a2[i%ARR_LEN+1]) +next +dsp_time( "j := val(a2[i%ARR_LEN+1]) -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + j := a2[i%ARR_LEN+1] == c +next +dsp_time( "j := a2[i%ARR_LEN+1] == s -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + j := a2[i%ARR_LEN+1] = c +next +dsp_time( "j := a2[i%ARR_LEN+1] = s -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + j := a2[i%ARR_LEN+1] >= c +next +dsp_time( "j := a2[i%ARR_LEN+1] >= s -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + j := a2[i%ARR_LEN+1] < c +next +dsp_time( "j := a2[i%ARR_LEN+1] < s -> ", t, tn) + +aa:={} +t:=secondscpu() +for i:=1 to N_LOOPS + if i%1000 == 0 + aa:={} + endif + aadd(aa,{i,j,c,a,a2,t,bc}) +next +dsp_time( "aadd(aa,{i,j,s,a,a2,t,bc}) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f0() +next +dsp_time( "f0() -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f1(i) +next +dsp_time( "f1(i) -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + f2(c) +next +dsp_time( "f2(c["+ltrim(str(len(c)))+"]) -> ", t, tn) + +c:=replicate(c,5000) +t:=secondscpu() +for i:=1 to N_LOOPS + f2(c) +next +dsp_time( "f2(c["+ltrim(str(len(c)))+"]) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f2(@c) +next +dsp_time( "f2(@c["+ltrim(str(len(c)))+"]) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f2(c) + c2:=c +next +dsp_time( "f2(c["+ltrim(str(len(c)))+"]); c2:=c -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f2(@c) + c2:=c +next +dsp_time( "f2(@c["+ltrim(str(len(c)))+"]); c2:=c -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + f3(a,a2,c,i,j,t,bc) +next +dsp_time( "f3(a,a2,c,i,j,t,bc) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + f2(a2) +next +dsp_time( "f2(a2) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + c:=f4() +next +dsp_time( "s:=f4() -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + c:=f5() +next +dsp_time( "s:=f5() -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + ascan(a,i%ARR_LEN) +next +dsp_time( "ascan(a,i%ARR_LEN) -> ", t, tn) + +c:=dtos(date()) +t:=secondscpu() +for i:=1 to N_LOOPS + ascan(a2,c+chr(i%64+64)) +next +dsp_time( "ascan(a2,c+chr(i%64+64)) -> ", t, tn) + +t:=secondscpu() +for i:=1 to N_LOOPS + ascan(a,{|x|x==i%ARR_LEN}) +next +dsp_time( "ascan(a,{|x|x==i%ARR_LEN}) -> ", t, tn) + +? replicate("=",60) +dsp_time( "total application time:", total, 0) +? padr( "total real time:",50)+str(seconds()-totalr,8,2) +? + +#ifndef NO_DBF_TEST + +if file(cFi1) + ferase(cFi1) +endif +if file(cFi2) + ferase(cFi2) +endif + +#endif + +return nil + +function dsp_time(s,t,tn) +? padr(s,50)+str(max(secondscpu()-t-tn,0),8,2) +return nil + +function f0(x) +return nil + +function f1(x) +return x+1 + +function f2(s) +return nil + +function f3(a,b,c,d,e,f,g,h,i) +return nil + +function f4() +return space(4000) + +function f5() +return space(5) + +function build_mode() +#ifdef __CLIP__ + return " (MT)" +#else + #ifdef __XHARBOUR__ + return iif( HB_MULTITHREAD(), " (MT)", "" ) + ; + iif( MEMORY( HB_MEM_USEDMAX ) != 0, " (FMSTAT)", "" ) + #else + #ifdef __HARBOUR__ + return iif( HB_MTVM(), " (MT)", "" ) + ; + iif( MEMORY( HB_MEM_USEDMAX ) != 0, " (FMSTAT)", "" ) + #else + #ifdef __XPP__ + return " (MT)" + #endif + #endif + #endif +#endif +return "" + +#ifdef FlagShip + function fs_seconds() + LOCAL_DOUBLE nret := 0 + #Cinline + { + #include + struct timeval tv; + struct timezone tz; + if( !gettimeofday(&tv, NULL) ) + nret = (double) tv.tv_sec + (double) (tv.tv_usec) / 1000000; +/* + nret = (double) (tv.tv_sec - tz.tz_minuteswest * 60 ) % 86400 + + (double) tv.tv_usec / 1000000; +*/ + } + #endCinline + return ( nret ) + + #ifndef FlagShip5 + FUNCTION cursesinit() + CALL fgsIoctl2 + #Cinline + { + #include + int arg; + if ((arg = fcntl(0, F_GETFL, 0)) != -1) + fcntl(0, F_SETFL, arg | O_NONBLOCK); + } + #endCinline + return nil + #endif +#endif + +#if __HARBOUR__ < 0x010100 +STATIC FUNCTION HB_MTVM() + RETURN .F. +#endif + +#ifndef __HARBOUR__ +STATIC FUNCTION hb_OSNewLine() +#ifdef FlagShip + RETURN Chr( 10 ) +#elif __CLIP__ + RETURN Chr( 10 ) +#else + RETURN Chr( 13 ) + Chr( 10 ) +#endif +#endif diff --git a/harbour/tests/speedtst.prg b/harbour/tests/speedtst.prg index 279a71184a..8afa3bf00d 100644 --- a/harbour/tests/speedtst.prg +++ b/harbour/tests/speedtst.prg @@ -4,513 +4,374 @@ /* * Harbour Project source code: - * a small speed test program + * HVM speed test program * - * Copyright 2006 Przemyslaw Czerpak + * Copyright 2008 Przemyslaw Czerpak * www - http://www.harbour-project.org * */ -#define ARR_LEN 16 + +#define N_TESTS 53 #define N_LOOPS 1000000 +#define ARR_LEN 16 -//#define NO_DBF_TEST -#define NO_KEYBOARD_TEST -#define NO_ASSOC_TEST - -#define REAL_TIME - -#ifdef __CLIP__ - #define ASSOC_ARRAY map() - #undef REAL_TIME -#endif -#ifdef FlagShip - #undef REAL_TIME - #xtranslate seconds() => fs_seconds() -#endif -#ifdef __HARBOUR__ - #include "hbmemory.ch" - #define ASSOC_ARRAY { => } - #undef REAL_TIME -#endif - -#ifdef REAL_TIME - #xtranslate secondscpu([]) => seconds() -#endif -#ifndef EOL - #define EOL hb_OSNewLine() -#endif #command ? => outstd(EOL) -#command ? => outstd(, EOL) +#command ? => outstd(EOL);outstd() -#ifdef NO_ASSOC_TEST - #undef ASSOC_ARRAY -#endif - -function main() -#ifndef NO_DBF_TEST -field F_C, F_N, F_D -#endif -memvar M_C, M_N, M_D -local L_C, L_N, L_D -local i, j, t, c, c2, n, d, o, bc, tn, total, totalr, aa,; - a[ARR_LEN], a2[ARR_LEN], a3[ARR_LEN], aDb, cFi1, cFi2 -#ifdef ASSOC_ARRAY - local aAssoc := ASSOC_ARRAY -#endif -private M_C := dtos(date()),; - M_N := 112345.67,; - M_D := date() - -#ifndef __CLIP__ -//#ifdef __HARBOUR__ -// setcancel(.f.) -// altd(0) -//#endif -#endif -#ifdef __CLIP__ - SET MACRO_IN_STRING OFF - //CLEAR SCREEN -#endif -#ifdef FlagShip - FS_SET( "zerobyte", .t. ) - FS_SET( "devel", .f. ) -// FS_SET( "break", 0 ) -// FS_SET( "debug", 0 ) -#endif - -for i:=1 to len(a) - a[i]:=i - a2[i]:=dtos(date())+chr(i%64+32)+chr(i%64+64)+str(i,10) - a3[i]:=stuff(dtos(date()),7,0,".") -next +#include "common.ch" #ifdef __HARBOUR__ + #define EOL hb_OSNewLine() +#else + #define HB_SYMBOL_UNUSED( symbol ) ( ( symbol ) ) + #ifndef __CLIP__ + #xtranslate secondsCPU() => seconds() + #endif + #ifndef EOL + #define EOL chr(10) + #endif +#endif + +#xcommand _( [] ) => [] + +#xcommand TEST ; + [ WITH ] ; + [ INIT ] ; + [ EXIT ] ; + [ INFO ] ; + CODE [<*testExp*>] => ; + func ; ; + local time, i, x := nil ; ; + [ local ; ] ; + [ ; ] ; + time := secondscpu() ; ; + for i:=1 to N_LOOPS ; ; + [;] ; + next ; ; + time := secondscpu() - time ; ; + [ ; ] ; + return { iif( <.info.>, <(info)>, # ), time } + + +proc main(mt) + test(mt) +return + + +#ifdef __XHARBOUR__ + + #xtranslate hb_mtvm() => hb_multiThread() + +#ifndef __ST__ + + /* do not expect that this code will work with xHarbour. + * xHarbour has many race conditions which are exploited quite fast + * on real multi CPU machines so it crashes in different places :-( + * probably this code should be forwared to xHarbour developers as + * some type of MT test + */ + + static function results( nTest, xResult ) + static s_aResults[ N_TESTS + 1 ] + if xResult == NIL + xResult := s_aResults[ nTest ] + else + s_aResults[ nTest ] := xResult + endif + return xResult + + /* I used function wrappers to simulate thread join which can + * return thread results + */ + static function do_test( cFunc ) + local x + ? "starting: " + cFunc + "()" + // if you set .f. then tests will be skipped but you can check + // if this test code is executed because it greatly reduces + // the race conditions inside xHarbour HVM + if .t. + x := &cFunc() + //dsp_result( x ) + else + x := { "skipped test " + cFunc, val( substr( cFunc, 2 ) ) + 0.99 } + endif + results( val( substr( cFunc, 2 ) ), x ) + return nil + + function hb_threadStart( cFunc ) + return StartThread( @do_test(), cFunc ) + + function hb_threadJoin( thId, xResult ) + static s_n := 0 + local lOK + /* in xHarbour there is race condition in JoinThread() which + * fails if thread end before we call it so we cannot use it :-( + */ + //lOK := JoinThread( thId ) + lOK := .t. + if s_n == 0 + HB_SYMBOL_UNUSED( thId ) + WaitForThreads() + endif + xResult := results( ++s_n ) + return lOK + +#else + + function hb_threadStart() + return nil + function hb_threadJoin() + return nil + +#endif + +#endif + + +TEST t000 INFO "empty loop overhead" CODE + +TEST t001 WITH L_C:=dtos(date()) CODE x := L_C + +TEST t002 WITH L_N:=112345.67 CODE x := L_N + +TEST t003 WITH L_D:=date() CODE x := L_D + +TEST t004 INIT _( static S_C ) INIT S_C:=dtos(date()) CODE x := S_C + +TEST t005 INIT _( static S_N ) INIT S_N:=112345.67 CODE x := S_N + +TEST t006 INIT _( static S_D ) INIT S_D:=date() CODE x := S_D + +TEST t007 INIT _( memvar M_C ) INIT _( private M_C:=dtos(date()) ) ; + CODE x := M_C + +TEST t008 INIT _( memvar M_N ) INIT _( private M_N:=112345.67 ) ; + CODE x := M_N + +TEST t009 INIT _( memvar M_D ) INIT _( private M_D:=date() ) ; + CODE x := M_D + +TEST t010 INIT _( memvar P_C ) INIT _( public P_C:=dtos(date()) ) ; + CODE x := P_C + +TEST t011 INIT _( memvar P_N ) INIT _( public P_N:=112345.67 ) ; + CODE x := P_N + +TEST t012 INIT _( memvar P_D ) INIT _( public P_D:=date() ) ; + CODE x := P_D + +TEST t013 INIT _( field F_C ) INIT use_dbsh() EXIT close_db() ; + CODE x := F_C + +TEST t014 INIT _( field F_N ) INIT use_dbsh() EXIT close_db() ; + CODE x := F_N + +TEST t015 INIT _( field F_D ) INIT use_dbsh() EXIT close_db() ; + CODE x := F_D + +TEST t016 WITH o := errorNew() CODE x := o:GenCode + +TEST t017 WITH o := errorNew() CODE x := 0 //o[8] + +TEST t018 CODE round( i / 1000, 2 ) + +TEST t019 CODE str( i / 1000 ) + +TEST t020 WITH s := stuff( dtos( date() ), 7, 0, "." ) CODE val( s ) + +TEST t021 WITH a := afill( array( ARR_LEN ), ; + stuff( dtos( date() ), 7, 0, "." ) ) ; + CODE val( a [ i % ARR_LEN + 1 ] ) + +TEST t022 WITH d := date() CODE dtos( d - i % 10000 ) + +TEST t023 CODE eval( { || i % ARR_LEN } ) + +TEST t024 WITH bc := { || i % ARR_LEN } ; + INFO eval( bc := { || i % ARR_LEN } ) ; + CODE eval( bc ) + +TEST t025 CODE eval( { |x| x % ARR_LEN }, i ) + +TEST t026 WITH bc := { |x| x % ARR_LEN } ; + INFO eval( bc := { |x| x % ARR_LEN }, i ) ; + CODE eval( bc, i ) + +TEST t027 CODE eval( { |x| f1( x ) }, i ) + +TEST t028 WITH bc := { |x| f1( x ) } ; + INFO eval( bc := { |x| f1( x ) }, i ) ; + CODE eval( bc, i ) + +TEST t029 CODE x := &( "f1(" + str(i) + ")" ) + +TEST t030 WITH bc CODE bc := &( "{|x|f1(x)}" ); eval( bc, i ) + +TEST t031 CODE x := valtype( x ) + valtype( i ) + +TEST t032 WITH a := afill( array( ARR_LEN ), ; + stuff( dtos( date() ), 7, 0, "." ) ) ; + CODE x := strzero( i % 100, 2 ) $ a[ i % ARR_LEN + 1 ] + +TEST t033 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] == s + +TEST t034 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] = s + +TEST t035 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] >= s + +TEST t036 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] <= s + +TEST t037 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] < s + +TEST t038 WITH a := array( ARR_LEN ), s := dtos( date() ) ; + INIT aeval( a, { |x,i| a[i] := left( s + s, i ), x } ) ; + CODE x := a[ i % ARR_LEN + 1 ] > s + +TEST t039 WITH a := array( ARR_LEN ) ; + INIT aeval( a, { |x,i| a[i] := i, x } ) ; + CODE ascan( a, i % ARR_LEN ) + +TEST t040 WITH a := array( ARR_LEN ) ; + INIT aeval( a, { |x,i| a[i] := i, x } ) ; + CODE ascan( a, { |x| x == i % ARR_LEN } ) + +TEST t041 WITH a := {}, a2 := { 1, 2, 3 }, bc := { |x| f1(x) }, ; + s := dtos( date() ), s2 := "static text" ; + CODE if i%1000==0;a:={};end; aadd(a,{i,1,.t.,s,s2,a2,bc}) + +TEST t042 WITH a := {} CODE x := a + +TEST t043 CODE x := {} + +TEST t044 CODE f0() + +TEST t045 CODE f1( i ) + +TEST t046 WITH c := dtos( date() ) ; + INFO f2( c[1...8] ) ; + CODE f2( c ) + +TEST t047 WITH c := repl( dtos( date() ), 5000 ) ; + INFO f2( c[1...40000] ) ; + CODE f2( c ) + +TEST t048 WITH c := repl( dtos( date() ), 5000 ) ; + INFO f2( @c[1...40000] ) ; + CODE f2( c ) + +TEST t049 WITH c := repl( dtos( date() ),5000 ), c2 ; + INFO "f2( @c[1...40000] ), c2 := c" ; + CODE f2( @c ); c2 := c + +TEST t050 WITH a := {}, a2 := { 1, 2, 3 }, bc := { |x| f1(x) }, ; + s := dtos( date() ), s2 := "static text", n := 1.23 ; + CODE f3( a, a2, s, i, s2, bc, i, n, x ) + +TEST t051 WITH a := { 1, 2, 3 } CODE f2( a ) + +TEST t052 CODE x := f4() + +TEST t053 CODE x := f5() + + +proc test(mt) +local nLoopOverHead, nTimes, nSeconds, x, i, aThreads:={} + +create_db() + +#ifdef __HARBOUR__ +#include "hbmemory.ch" if MEMORY( HB_MEM_USEDMAX ) != 0 - ? ? "Warning !!! Memory statistic enabled." + ? endif #endif -? -? "Startup loop to increase CPU clock..." -t:=seconds()+5; while t > seconds(); enddo -? -? date(), time(), VERSION()+build_mode()+", "+OS() -? "ARR_LEN =", ARR_LEN +? "Startup loop to increase CPU clock..." +x := seconds() + 5; while x > seconds(); enddo + +? date(), time(), os() +#ifdef __HARBOUR__ + ? version() + iif( hb_mtvm(), " (MT)", "" ), hb_compiler() +#else + ? version() +#endif ? "N_LOOPS =", N_LOOPS -t:=secondscpu() -for i:=1 to N_LOOPS -next -tn:=secondscpu()-t -? "empty loops overhead =", tn -#ifdef REAL_TIME - ? "real time -> seconds()" -#else - ? "CPU usage -> secondsCPU()" -#endif -? "" +x :=t000() +? dsp_result( x, 0 ) +nLoopOverHead := x[2] -#ifndef NO_DBF_TEST +? replicate("=",68) -aDb:={ {"F_C", "C", 10, 0},; - {"F_N", "N", 10, 2},; - {"F_D", "D", 8, 0} } - -cFi1:="tst_tmp.dbf" -if file(cFi1) - ferase(cFi1) -endif -dbcreate(cFi1, aDb) -select(1) -use &cFi1 shared -dbappend() -replace F_C with dtos(date()) -replace F_N with 112345.67 -replace F_D with date() -dbcommit() -dbunlock() - -cFi2:="tst_tmp2.dbf" -if file(cFi2) - ferase(cFi2) -endif -dbcreate(cFi2, aDb) -select(2) -use &cFi2 exclusive -dbappend() -replace F_C with dtos(date()) -replace F_N with 112345.67 -replace F_D with date() -dbcommit() -dbunlock() - -#endif - -L_C := dtos(date()) -L_N := 112345.67 -L_D := date() - - -total:=secondscpu() -totalr:=seconds() -t:=secondscpu() -for i:=1 to N_LOOPS - c:=L_C -next -dsp_time( "c:=L_C -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - n:=L_N -next -dsp_time( "n:=L_N -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - d:=L_D -next -dsp_time( "d:=L_D -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - c:=M_C -next -dsp_time( "c:=M_C -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - n:=M_N -next -dsp_time( "n:=M_N -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - d:=M_D -next -dsp_time( "d:=M_D -> ", t, tn) - -#ifndef NO_DBF_TEST -select(1) -t:=secondscpu() -for i:=1 to N_LOOPS - c:=F_C -next -dsp_time( "(sh) c:=F_C -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - n:=F_N -next -dsp_time( "(sh) n:=F_N -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - d:=F_D -next -dsp_time( "(sh) d:=F_D -> ", t, tn) - -select(2) -t:=secondscpu() -for i:=1 to N_LOOPS - c:=F_C -next -dsp_time( "(ex) c:=F_C -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - n:=F_N -next -dsp_time( "(ex) n:=F_N -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - d:=F_D -next -dsp_time( "(ex) d:=F_D -> ", t, tn) -#endif - -o:=errorNew() -t:=secondscpu() -for i:=1 to N_LOOPS - n:=o:GenCode -next -dsp_time( "n:=o:GenCode -> ", t, tn) +nSeconds := seconds() +nTimes := secondsCPU() #ifdef __HARBOUR__ -t:=secondscpu() -for i:=1 to N_LOOPS - n:=o[8] -next -dsp_time( "n:=o[8] -> ", t, tn) + if !empty(mt) .and. hb_mtvm() + aThreads := array( N_TESTS ) + for i:=1 to N_TESTS + aThreads[ i ] := hb_threadStart( "t" + strzero( i, 3 ) ) + next + for i:=1 to N_TESTS + if hb_threadJoin( aThreads[ i ], @x ) + ? dsp_result( x, nLoopOverHead ) + endif + next + else + for i:=1 to N_TESTS + ? dsp_result( &( "t" + strzero( i, 3 ) )(), nLoopOverHead ) + next + endif +#else + for i:=1 to N_TESTS + ? dsp_result( &( "t" + strzero( i, 3 ) )(), nLoopOverHead ) + next #endif -#ifdef ASSOC_ARRAY -t:=secondscpu() -for i:=1 to N_LOOPS - aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100))]:=i -next -dsp_time( "aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100)]:=i -> ", t, tn) +nTimes := secondsCPU() - nTimes +nSeconds := seconds() - nSeconds -t:=secondscpu() -for i:=1 to N_LOOPS - c:=aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100))] -next -dsp_time( "c:=aAssoc[a2[i%ARR_LEN+1]+ltrim(str(i%100)] -> ", t, tn) -#endif - -#ifndef NO_KEYBOARD_TEST -t:=secondscpu() -for i:=1 to N_LOOPS - inkey() -next -dsp_time( "inkey() -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - nextkey() -next -dsp_time( "nextkey() -> ", t, tn) -#endif - -t:=secondscpu() -for i:=1 to N_LOOPS - round(i/1000,2) -next -dsp_time( "round(i/1000,2) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - str(i/1000) -next -dsp_time( "str(i/1000) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - val(a3[i%ARR_LEN+1]) -next -dsp_time( "val(a3[i%ARR_LEN+1]) -> ", t, tn) - -t:=secondscpu() -j:=date() -for i:=1 to N_LOOPS - dtos(j+i%10000-5000) -next -dsp_time( "dtos(j+i%10000-5000) -> ", t, tn) - -bc:={||i%ARR_LEN} -t:=secondscpu() -for i:=1 to N_LOOPS - eval(bc) -next -dsp_time( "eval({||i%ARR_LEN}) -> ", t, tn) - -bc:={|x|x%ARR_LEN} -t:=secondscpu() -for i:=1 to N_LOOPS - eval(bc,i) -next -dsp_time( "eval({|x|x%ARR_LEN},i) -> ", t, tn) - -bc:={|x|f1(x)} -t:=secondscpu() -for i:=1 to N_LOOPS - eval(bc,i) -next -dsp_time( "eval({|x|f1(x)},i) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - n:=&("f1("+str(i)+")") -next -dsp_time( "&('f1('+str(i)+')') -> ", t, tn) - -bc:=&("{|x|f1(x)}") -t:=secondscpu() -for i:=1 to N_LOOPS - eval(bc,i) -next -dsp_time( "eval([&('{|x|f1(x)}')]) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - j:=valtype(a)+valtype(i) -next -dsp_time( "j := valtype(a)+valtype(i) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - j := str(i%100,2) $ a2[i%ARR_LEN+1] -next -dsp_time( "j := str(i%100,2) $ a2[i%ARR_LEN+1] -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - j := val(a2[i%ARR_LEN+1]) -next -dsp_time( "j := val(a2[i%ARR_LEN+1]) -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - j := a2[i%ARR_LEN+1] == c -next -dsp_time( "j := a2[i%ARR_LEN+1] == s -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - j := a2[i%ARR_LEN+1] = c -next -dsp_time( "j := a2[i%ARR_LEN+1] = s -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - j := a2[i%ARR_LEN+1] >= c -next -dsp_time( "j := a2[i%ARR_LEN+1] >= s -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - j := a2[i%ARR_LEN+1] < c -next -dsp_time( "j := a2[i%ARR_LEN+1] < s -> ", t, tn) - -aa:={} -t:=secondscpu() -for i:=1 to N_LOOPS - if i%1000 == 0 - aa:={} - endif - aadd(aa,{i,j,c,a,a2,t,bc}) -next -dsp_time( "aadd(aa,{i,j,s,a,a2,t,bc}) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f0() -next -dsp_time( "f0() -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f1(i) -next -dsp_time( "f1(i) -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - f2(c) -next -dsp_time( "f2(c["+ltrim(str(len(c)))+"]) -> ", t, tn) - -c:=replicate(c,5000) -t:=secondscpu() -for i:=1 to N_LOOPS - f2(c) -next -dsp_time( "f2(c["+ltrim(str(len(c)))+"]) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f2(@c) -next -dsp_time( "f2(@c["+ltrim(str(len(c)))+"]) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f2(c) - c2:=c -next -dsp_time( "f2(c["+ltrim(str(len(c)))+"]); c2:=c -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f2(@c) - c2:=c -next -dsp_time( "f2(@c["+ltrim(str(len(c)))+"]); c2:=c -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - f3(a,a2,c,i,j,t,bc) -next -dsp_time( "f3(a,a2,c,i,j,t,bc) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - f2(a2) -next -dsp_time( "f2(a2) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - c:=f4() -next -dsp_time( "s:=f4() -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - c:=f5() -next -dsp_time( "s:=f5() -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - ascan(a,i%ARR_LEN) -next -dsp_time( "ascan(a,i%ARR_LEN) -> ", t, tn) - -c:=dtos(date()) -t:=secondscpu() -for i:=1 to N_LOOPS - ascan(a2,c+chr(i%64+64)) -next -dsp_time( "ascan(a2,c+chr(i%64+64)) -> ", t, tn) - -t:=secondscpu() -for i:=1 to N_LOOPS - ascan(a,{|x|x==i%ARR_LEN}) -next -dsp_time( "ascan(a,{|x|x==i%ARR_LEN}) -> ", t, tn) - -? replicate("=",60) -dsp_time( "total application time:", total, 0) -? padr( "total real time:",50)+str(seconds()-totalr,8,2) +? replicate("=",68) +? dsp_result( { "total application time:", nTimes }, 0) +? dsp_result( { "total real time:", nSeconds }, 0 ) ? -#ifndef NO_DBF_TEST +remove_db() +return -if file(cFi1) - ferase(cFi1) -endif -if file(cFi2) - ferase(cFi2) -endif -#endif - -return nil - -function dsp_time(s,t,tn) -? padr(s,50)+str(max(secondscpu()-t-tn,0),8,2) -return nil - -function f0(x) +function f0() return nil function f1(x) -return x+1 +return x -function f2(s) +function f2(x) +HB_SYMBOL_UNUSED( x ) return nil function f3(a,b,c,d,e,f,g,h,i) +HB_SYMBOL_UNUSED( a ) +HB_SYMBOL_UNUSED( b ) +HB_SYMBOL_UNUSED( c ) +HB_SYMBOL_UNUSED( d ) +HB_SYMBOL_UNUSED( e ) +HB_SYMBOL_UNUSED( f ) +HB_SYMBOL_UNUSED( g ) +HB_SYMBOL_UNUSED( h ) +HB_SYMBOL_UNUSED( i ) return nil function f4() @@ -519,71 +380,34 @@ return space(4000) function f5() return space(5) -function build_mode() -#ifdef __CLIP__ - return " (MT)" -#else - #ifdef __XHARBOUR__ - return iif( HB_MULTITHREAD(), " (MT)", "" ) + ; - iif( MEMORY( HB_MEM_USEDMAX ) != 0, " (FMSTAT)", "" ) - #else - #ifdef __HARBOUR__ - return iif( HB_MTVM(), " (MT)", "" ) + ; - iif( MEMORY( HB_MEM_USEDMAX ) != 0, " (FMSTAT)", "" ) - #else - #ifdef __XPP__ - return " (MT)" - #endif - #endif - #endif -#endif -return "" -#ifdef FlagShip - function fs_seconds() - LOCAL_DOUBLE nret := 0 - #Cinline - { - #include - struct timeval tv; - struct timezone tz; - if( !gettimeofday(&tv, NULL) ) - nret = (double) tv.tv_sec + (double) (tv.tv_usec) / 1000000; -/* - nret = (double) (tv.tv_sec - tz.tz_minuteswest * 60 ) % 86400 + - (double) tv.tv_usec / 1000000; -*/ - } - #endCinline - return ( nret ) +static func dsp_result( aResult, nLoopOverHead ) + return padr( "[ " + left( aResult[1], 56 ) + " ]", 60, "." ) + ; + strtran( str( max( aResult[2] - nLoopOverHead, 0 ), 8, 2 ), " ", "." ) - #ifndef FlagShip5 - FUNCTION cursesinit() - CALL fgsIoctl2 - #Cinline - { - #include - int arg; - if ((arg = fcntl(0, F_GETFL, 0)) != -1) - fcntl(0, F_SETFL, arg | O_NONBLOCK); - } - #endCinline - return nil - #endif -#endif -#if __HARBOUR__ < 0x010100 -STATIC FUNCTION HB_MTVM() - RETURN .F. -#endif +#define TMP_FILE "_tst_tmp.dbf" +static proc create_db() + remove_db() + dbcreate( TMP_FILE, { {"F_C", "C", 10, 0},; + {"F_N", "N", 10, 2},; + {"F_D", "D", 8, 0} } ) + use TMP_FILE exclusive + dbappend() + replace F_C with dtos(date()) + replace F_N with 112345.67 + replace F_D with date() + close +return -#ifndef __HARBOUR__ -STATIC FUNCTION hb_OSNewLine() -#ifdef FlagShip - RETURN Chr( 10 ) -#elif __CLIP__ - RETURN Chr( 10 ) -#else - RETURN Chr( 13 ) + Chr( 10 ) -#endif -#endif +static proc remove_db() + ferase( TMP_FILE ) +return + +static proc close_db() + close +return + +static proc use_dbsh() + use TMP_FILE shared +return