vendredi 30 mai 2014

Why is Console.WriteLine speeding up my application?


Vote count:

0




Ok so this is kind of weird. I have an algorithm to find the highest possible numerical palindrome that is a multiple of two factors who each have K digits.


The method I'm using to find the highest valid palindrome is to look at the highest possible palindrome for the number set (i.e. if k=3, the highest possible is 999999, then 998899, etc). Then I check if that palindrome has two factors with K digits.


For debugging, I thought it would be a good idea to print to the console each of the palindromes I was checking (to make sure I was getting them all. To my surprise, adding



Console.WriteLine(palindrome.ToString());


to each iteration of finding a palindrome dropped my runtime a whopping 10 seconds from ~24 to ~14.


To verify, I ran the program several times, then commented out the Console command and ran that several times, and every time it was shorter with the Console command.


This just seems weird, any ideas?


Here's the source if anyone wants to take a whack at it:



static double GetHighestPalindromeBench(int k)
{
//Because the result of k == 1 is a known quantity, and results in aberrant behavior in the algorithm, handle as separate case
if (k == 1)
{
return 9;
}


/////////////////////////////////////
//These variables will be used in HasKDigitFactors(), no need to reprocess them each time the function is called
double kTotalSpace = 10;

for (int i = 1; i < k; i++)
{
kTotalSpace *= 10;
}

double digitConstant = kTotalSpace; //digitConstant is used in HasKDigits() to determine if a factor has the right number of digits

double kFloor = kTotalSpace / 10; //kFloor is the lowest number that has k digits (e.g. k = 5, kFloor = 10000)

double digitConstantFloor = kFloor - digitConstant; //also used in HasKDigits()

kTotalSpace--; //kTotalSpace is the highest number that has k digits (e.g. k = 5, kTotalSpace = 99999)

/////////////////////////////////////////


double totalSpace = 10;

double halfSpace = 10;

int reversionConstant = k;

for (int i = 1; i < k * 2; i++)
{
totalSpace *= 10;
}

double floor = totalSpace / 100;

totalSpace--;


for (int i = 1; i < k; i++)
{
halfSpace *= 10;
}

double halfSpaceFloor = halfSpace / 10; //10000

double halfSpaceStart = halfSpace - 1; //99999

for (double i = halfSpaceStart; i > halfSpaceFloor; i--)
{
double value = i;
double palindrome = i;
//First generate the full palindrome
for (int j = 0; j < reversionConstant; j++)
{
int digit = (int)value % 10;

palindrome = palindrome * 10 + digit;

value = value / 10;
}

Console.WriteLine(palindrome.ToString());
//palindrome should be ready
//Now we check the factors of the palindrome to see if they match k
//We only need to check possible factors between our k floor and ceiling, other factors do not solve
if (HasKDigitFactors(palindrome, kTotalSpace, digitConstant, kFloor, digitConstantFloor))
{
return palindrome;
}
}


return 0;
}

static bool HasKDigitFactors(double palindrome, double totalSpace, double digitConstant, double floor, double digitConstantFloor)
{
for (double i = floor; i <= totalSpace; i++)
{
if (palindrome % i == 0)
{
double factor = palindrome / i;
if (HasKDigits(factor, digitConstant, digitConstantFloor))
{
return true;
}
}
}
return false;
}

static bool HasKDigits(double value, double digitConstant, double digitConstantFloor)
{
//if (Math.Floor(Math.Log10(value) + 1) == k)
//{
// return true;
//}
if (value - digitConstant > digitConstantFloor && value - digitConstant < 0)
{
return true;
}

return false;
}


Note that I have the Math.Floor operation in HasKDigits commented out. This all started when I was trying to determine if my digit check operation was faster than the Math.Floor operation. Thanks!


EDIT: Function call


I'm using StopWatch to measure processing time. I also used a physical stopwatch to verify the results of StopWatch.



Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
double palindrome = GetHighestPalindromeBench(6);
stopWatch.Stop();

TimeSpan ts = stopWatch.Elapsed;

string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}:{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

Console.WriteLine();
Console.WriteLine(palindrome.ToString());
Console.WriteLine();
Console.WriteLine(elapsedTime);





asked 14 mins ago






Aucun commentaire:

Enregistrer un commentaire