/**********************************************************************/
/*   Functions to do some performance monitoring.		      */
/**********************************************************************/

# define	UNITS	1000000

list	tests = {
	"loop",
	"macro_list",
	"command_list",
	"strcat",
	"string_assign",
	"get_nth",
	"put_nth",
	"if",
	"trim",
	"compress",
	"loop_float",
	"sieve"
	};

void
main()
{	
	autoload("sieve", "calc_primes");
}
/**********************************************************************/
/*   Perform  a  set  of  performance  tests.  These  are  used  for  */
/*   performance  comparisons  across  processor ranges and for some  */
/*   regression testing.					      */
/**********************************************************************/
void
perf(int arg)
{	int	h, m, s;
	int	d, y;
	int	i;
	int	maj, min, edit;
	string	mon;
	string	buf;
	int	stime;
	
	date(y, NULL, d, mon);
	time(h, m, s);
	edit_file("PERF.log");
	end_of_buffer();
	version(maj, min, edit);
	sprintf(buf, "\n%d %s %d %02d:%02d v%d.%d%c\n", d, mon, y, h, m,
		maj, min, edit);
	insert(buf);
	set_bottom_of_window();
	refresh();

	stime = inq_clock();	
	/***********************************************/
	/*   If  user  only  wants  a  specific  test  */
	/*   then make sure its in range.	       */
	/***********************************************/
	if (arg >= 1 && arg <= length_of_list(tests))
		perf_time(arg, tests[arg - 1]);
	else {
		/***********************************************/
		/*   Start of tests..			       */
		/***********************************************/
		for (i = 0; i < length_of_list(tests); i++)
			perf_time(i+1, tests[i]);
		}
	stime = inq_clock() - stime;
	sprintf(buf, "                     Total: %d.%06d\n", stime / UNITS, stime % UNITS);
	insert(buf);
}
void
assert(int cond)
{
	if (cond == 0)
		error("Assertion failed.");
}
string
perf_time(int test, string mac)
{
	int	s, e;
	string	str;

	sprintf(str, "  %d) %s", test, mac);
	insert(str);
	move_abs(0, 24);
	refresh();
	s = inq_clock();
	execute_macro("pf_" + mac);
	e = inq_clock();
	str = display_time(s, e);
	insert(str);
	insert("\n");
	refresh();
}
string
display_time(int s, int e)
{
	int	sec = (e - s) / UNITS;
	int	usec = (e - s) % UNITS;
	string	buf;
	
	sprintf(buf, "Time: %d.%02d", sec, usec / 10000);
	return buf;
	
}
void
pf_loop()
{
	int	i;
	for (i = 0; i < 30000; i++)
		;
}
void
pf_macro_list()
{
	int	i;
	for (i = 0; i < 1000; i++)
		macro_list();
}
void
pf_command_list()
{
	int	i;
	for (i = 0; i < 1000; i++)
		command_list();
}
void
pf_strcat()
{	int	i, j;
	string	s;
	
	for (i = 0; i < 1000; i++) {
		s = "";
		for (j = 0; j < 10; j++)
			s += "A";
		}
}
void
pf_string_assign()
{
	int	i;
	string	s;
	
	for (i = 0; i < 10000; i++)
		s = "abc" + "def";
}
void
pf_get_nth()
{	int	i;
	list	l;
	declare	x, y, z;
	
	for (i = 0; i < 2500; i++) {
		l = quote_list("ABC", "DEF", "GHI");
		x = l[0];
		y = l[1];
		z = l[2];
		}
}
void
pf_put_nth()
{	int	i;
	list	l;
	
	for (i = 0; i < 5000; i++) {
		l = NULL;
		l[0] = 123;
		l[1] = "abc" + "def";
		l[2] = quote_list(1, 2, 3);
		}
}
void
pf_if()
{	int	i;
	string	s;

	for (i = 0; i < 10000; i++)
		if ((s = "abc") == "def")
			break;
}
void
pf_trim()
{	int	i;
	string	s;

	for (i = 0; i < 1000; i++) {
		s = trim("abc \n");
		assert(s == "abc");
		s = ltrim("xxabc", "xx");
		assert(s == "abc");
		s = trim("\n");
		assert(s == "");
		}
}
void
pf_compress()
{	int	i;
	string	s;

	for (i = 0; i < 5000; i++) {
		s = compress(ltrim(trim("\n")));
		assert(s == "");
		}
}
void
pf_loop_float()
{
	float	i;
	for (i = 0; i < 30000; i++)
		;
}
void
pf_sieve()
{
	calc_primes(1000);
}
