//---------------------------------------------------------------------------

#include <fmx.h>
#pragma hdrstop

#include "MainForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

inline bool naive_char(const char *a, const char *b) {
	while (*a || *b) {
		if (*a != *b) {
			return false;
		}
		++a;
		++b;
	}
	return true;
}

inline bool naive_string(const std::string& a, const std::string& b) {
	if (a.length() == b.length()) {
		return naive_char(a.c_str(), b.c_str());
	}
	return false;
}

static const size_t N = 1000;
static const size_t R = 7;

long TForm1::getTime()
{
	return GetTickCount();
}

void TForm1::ShowRunTime(TEdit* pEdit, const long lTime)
{
	pEdit->Text = FloatToStr(lTime / 1000.0) + "¬í";
}

void TForm1::NativeTest()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (naive_char(chars[i], chars[i-1]))
			{
				++tlen;
			}
		}
	}
}

void TForm1::DoStringTest1()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	NativeTest();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest1, (lEnd - lStart));
}

void TForm1::StringStringTest()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (naive_string(strings[i], strings[i-1]))
			{
				++tlen;
			}
		}
	}
}

void TForm1::DoStringTest2()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStringTest();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest2, (lEnd - lStart));
}

void TForm1::StringEqualTest()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strings[i] == strings[i-1])
			{
				++tlen;
			}
		}
	}
}

void TForm1::DoStringTest3()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringEqualTest();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest3, (lEnd - lStart));
}

void TForm1::StringCharTest()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strings[i] == chars[i-1])
			{
				++tlen;
			}
		}
	}
}

void TForm1::DoStringTest4()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringCharTest();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest4, (lEnd - lStart));
}

void TForm1::StringStrcmpTest1()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i) {
			if (strcmp(chars[i], chars[i-1]) == 0)
			{
				++tlen;
			}
		}
	}
//	this->Caption = IntToStr((int) tlen);
}

void TForm1::StringStrcmpTest2()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strcmp(chars[i], strings[i-1].c_str()) == 0) {
				++tlen;
			}
		}
	}
}

void TForm1::StringStrcmpTest3()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strcmp(strings[i].c_str(), strings[i-1].c_str()) == 0)
			{
				++tlen;
			}
		}
	}
}

void TForm1::StringStrcmpTest4()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strings[i].compare(strings[i-1]) == 0)
			{
				++tlen;
			}
		}
	}
}

void TForm1::StringStrcmpTest5()
{
	size_t tlen = 0;
	for (size_t r=0 ; r<R ; ++r)
	{
		for (size_t i=1 ; i<N ; ++i)
		{
			if (strings[i].compare(chars[i-1]) == 0)
			{
				++tlen;
			}
		}
	}
}

void TForm1::DoStringTest5()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStrcmpTest1();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest5, (lEnd - lStart));
}

void TForm1::DoStringTest6()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStrcmpTest2();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest6, (lEnd - lStart));
}

void TForm1::DoStringTest7()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStrcmpTest3();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest7, (lEnd - lStart));
}

void TForm1::DoStringTest8()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStrcmpTest4();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest8, (lEnd - lStart));
}

void TForm1::DoStringTest9()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StringStrcmpTest5();
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest9, (lEnd - lStart));
}

int TForm1::StingBuilderTest(char *s)
{
	TStringBuilder *pSB = new TStringBuilder();
	pSB->Append("This is test.");
	pSB->Append(" And it continues: ");
	pSB->Append(s);
	pSB->Append(". All done!");
	int iResult = pSB->Length;
	delete pSB;
	return iResult;
}

void TForm1::DoStringTest10()
{
  lStart = getTime();
  for (int iLoop = 1; iLoop <= StrToInt(edtTestLoops->Text); iLoop++)
  {
	StingBuilderTest("This is StringBuilder Test");
  }
  lEnd = getTime();
  ShowRunTime(edtStringTest10, (lEnd - lStart));
}


void __fastcall TForm1::btnGoClick(TObject *Sender)
{
  DoStringTest1();
  Application->ProcessMessages();
  DoStringTest2();
  Application->ProcessMessages();
  DoStringTest3();
  Application->ProcessMessages();
  DoStringTest4();
  Application->ProcessMessages();
  DoStringTest5();
  Application->ProcessMessages();
  DoStringTest6();
  Application->ProcessMessages();
  DoStringTest7();
  Application->ProcessMessages();
  DoStringTest8();
  Application->ProcessMessages();
  DoStringTest9();
  Application->ProcessMessages();
  DoStringTest10();
}
//---------------------------------------------------------------------------

void TForm1::DoStringInit()
{
    chars.reserve(N);
    strings.reserve(N);
    for (size_t i=0 ; i<N ; ++i) {
        char *s = new char[12];
        sprintf(s, "%u", uint32_t(i));
        chars.push_back(s);
        strings.push_back(s);
        strings.back().c_str();
	}
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  if ((int) sizeof(void*) == 4)
	this->Caption = this->Caption  + " 32BIT";
  else
	this->Caption = this->Caption  + " 64BIT";

  DoStringInit();
}
//---------------------------------------------------------------------------

