为什么Console.WriteLine加速我的应用程序? [英] Why is Console.WriteLine speeding up my application?

查看:355
本文介绍了为什么Console.WriteLine加速我的应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好了,所以这是一种奇怪的。我有一个算法来寻找可能的最高数字回文这是两个因素各自谁的K个数字的倍数。



我使用的是找到最有效的方法回文是看在尽可能高的回文人数为一组(即当k = 3时,最高的是999999,那么998899等)。然后,我检查了回文有两个因素,用K位。



有关调试,我认为这将是打印到控制台,每个我是回文一个好主意检查(以确保我得到他们。让我吃惊的是,加入

  Console.WriteLine(palindrome.ToString()) ; 

从找到一个回文翻掉运行时间高达10秒每次迭代〜24〜14



要验证,我跑程序数次,然后注释掉控制台命令,跑了好几次,每次更短的控制台命令。



这只是似乎不可思议,任何想法?



下面是源,如果有人想采取捶一下:

 静态双GetHighestPalindromeBench(INT K)
{
//因为满足K == 1的结果是一个已知量,并导致在算法异常行为,处理为单独的壳体
如果(K == 1)
{
返回9;
}


///////////////////////////////// ////
//这些变量将在HasKDigitFactors(),无需每次重新处理它们的函数被调用
使用双kTotalSpace = 10;

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

双digitConstant = kTotalSpace; // digitConstant在HasKDigits使用()来确定一个系数有位

正确数量的双kFloor = kTotalSpace / 10; // kFloor是有k个位数最低的数字(例如K = 5,kFloor = 10000)

双digitConstantFloor = kFloor - digitConstant; //在HasKDigits也使用()

kTotalSpace--; // kTotalSpace是有k个位数(例如K = 5,kTotalSpace = 99999)

数最高///////////////////// ////////////////////


双totalSpace = 10;

双半空间= 10;

INT reversionConstant = K;

的for(int i = 1; I< K * 2;我++)
{
totalSpace * = 10;
}

双楼= totalSpace / 100;

totalSpace--;


的for(int i = 1; I< k;我++)
{
半空间* = 10;
}

双halfSpaceFloor =半空间/ 10; // 10000

双halfSpaceStart =半空间 - 1; // 99999

为(双I = halfSpaceStart; I> halfSpaceFloor;我 - )
{
double值=我;
双回文= I;
//首先生成完整的回文
(INT J = 0; J< reversionConstant; J ++)
{
INT位=(int)的值10%;

回文=回文* 10 +数字;

值=值/ 10;
}

Console.WriteLine(palindrome.ToString());
//回文应该准备
//现在我们检查的回文的因素,以查看它们是否匹配ķ
//我们只需要检查日K地板和天花板之间可能的因素,其他因素不解决
如果(HasKDigitFactors(回文,kTotalSpace,digitConstant,kFloor,digitConstantFloor))
{
返回回文;
}
}


返回0;
}

静态布尔HasKDigitFactors(双回文,双totalSpace,双digitConstant,双楼,双digitConstantFloor)
{
为(双I =地板; I< = totalSpace;我++)
{
如果(回文%我== 0)
{
双因子=回文/ I;
如果(HasKDigits(因子,digitConstant,digitConstantFloor))
{
返回真;
}
}
}
返回false;
}

静态布尔HasKDigits(双精度值,双digitConstant,双digitConstantFloor)
{
//如果(Math.Floor(Math.Log10(值)+ 1)== K)
// {
//返回true;
//}
如果(价值 - digitConstant> digitConstantFloor和放大器;&安培;价值 - digitConstant℃下)
{
返回真;
}

返回FALSE;
}

请注意,我在HasKDigits的Math.Floor操作注释掉。当我试图确定我的数字检查操作比Math.Floor操作更快这一切开始。 !谢谢



编辑:函数调用



我用秒表测量处理时间。我也用一个物理秒表来验证秒表的结果。



 秒表=新的秒表(); 
stopWatch.Start();
双回文= GetHighestPalindromeBench(6);
stopWatch.Stop();

时间跨度TS = stopWatch.Elapsed;

串elapsedTime =的String.Format({0点00分} {1时00分} {}二点:{}三时,ts.Hours,ts.Minutes,TS .Seconds,ts.Milliseconds / 10);

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


解决方案

我已经测试你的代码。我的系统是一个i7-3770 3.40 GHz的四核超线程,因此可用8个内核。



调试版本,有和没有控制台的WriteLine语句(注释掉或没有),在调试模式与否,时间从大约8.7到9.8秒的不同而不同。作为一个发布版本它归结为约6.8-7.0秒两种方式。个数字是相同的内部VS和命令行。所以,你的观察是不再现。



在没有控制台输出性能监视器我看到100%的一个核心,但核心1,4,5和8之间切换。如果没有控制台输出上有其它核活动。最大CPU使用率不超过18%。



在我的判断与控制台输出的数字可能与我一致,代表了真正的价值。所以,你的问题应该是:为什么是你的系统这么慢,当它没有做控制台输出



答案是:因为有一些关于您的计算机或项目的不同而我们不知道。我从来没见过这样的事,但都吸纳了周期,你应该能够找出它是什么。



我写这作为一个答案,虽然这是不是一个真正的答案。如果你得到更多的事实和更新你的问题,希望我能提供一个更好的答案。


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);

解决方案

I have tested your code. My system is an i7-3770 3.40 GHz, quad-core with hyperthreading, so 8 cores available.

Debug build, with and without the console Writeline statement (commented out or not), in debug mode or not, the times vary from about 8.7 to 9.8 sec. As a Release build it comes down to about 6.8-7.0 sec either way. Th figures were the same inside VS and from the command line. So your observation is not reproduced.

On performance monitor with no console output I see one core at 100%, but it switches between cores 1,4,5 and 8. Without console output there is activity on other cores. Max CPU usage never exceeds 18%.

In my judgment your figure with console output is probably consistent with mine, and represents the true value. So your question should read: why is your system so slow when it's not doing console output?

The answer is: because there is something different about your computer or your project which we don't know about. I've never seen this before, but something is soaking up cycles and you should be able to find out what it is.

I've written this as an answer although it isn't really an answer. If you get more facts and update your question, hopefully I can provide a better answer.

这篇关于为什么Console.WriteLine加速我的应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆