解析性能(如,的TryParse,尝试捕获) [英] Parsing Performance (If, TryParse, Try-Catch)

查看:106
本文介绍了解析性能(如,的TryParse,尝试捕获)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道很多关于处理信息解析文本的不同方式。解析例如整数,可以预期什么样的表现。我想知道,如果有人对此有任何好的统计都知道。我要寻找从别人一些真正的数字谁也测试了这一点。

哪个这些优惠的最佳性能在哪些情况?

 解析(...)//如果崩溃的情况是极为罕见的0.0001%如果(SomethingIsValid)//解析之前检查值
    解析(...)的TryParse(...)//使用的TryParse尝试
{
    解析(...)
}
抓住
{
    //捕获任何抛出的异常
}


解决方案

总是使用 T.TryParse(字符串str出的T值)。抛出异常是昂贵的,应该尽量避免,如果你能处理这种情况的先验的。使用try-catch块性能拯救(因为你的无效数据率低)是例外的可维护性为代价处理和良好的编码实践的滥用。按照完善的软件工程开发实践,编写测试用例,运行你的应用程序,然后基准和优化。


  

我们应该忘记小的效率,例如约97%的时间: premature优化是一切罪恶的根源然而,我们不应该错过我们在这一关键3的机会。 %-Donald克努特


因此​​,你分配的​​,任意像碳信用额,那的try-catch的性能的更糟的和的TryParse的性能的更好的。我们已经运行我们的应用程序,并确定只有在我们拥有某种放缓w.r.t.的字符串分析会,我们甚至考虑使用比其他的TryParse东西。

(编辑:因为它出现的提问想定时数据一起去很好的意见,在这里是请求的时序数据)

为10,000投入各种故障率从用户(不信)时间:

 故障率尝试捕获放缓的TryParse
  0%00:00:00.0131758 00:00:00.0120421 0.1
 10%00:00:00.1540251 00:00:00.0087699 16.6
 20%00:00:00.2833266 00:00:00.0105229 25.9
 30%00:00:00.4462866 00:00:00.0091487 47.8
 40%00:00:00.6951060 00:00:00.0108980 62.8
 50%00:00:00.7567745 00:00:00.0087065 85.9
 60%00:00:00.7090449 00:00:00.0083365 84.1
 70%00:00:00.8179365 00:00:00.0088809 91.1
 80%00:00:00.9468898 00:00:00.0088562 105.9
 90%00:00:01.0411393 00:00:00.0081040 127.5
100%00:00:01.1488157 00:00:00.0078877 144.6
///< PARAM NAME =ERRORRATE>年率在用户输入与LT的错误; /参数>
///<退货和GT;采取&LT总时间; /回报>
公共静态时间跨度TimeTryCatch(双ERRORRATE,诠释种子,诠释计数)
{
    秒表=新的秒表();
    随机随机=新的随机(种子);
    字符串bad_ preFIX = @X;    stopwatch.Start();
    为(中间体二= 0; II蛋白酶;计数++ⅱ)
    {
        字符串输入= random.Next()的ToString()。
        如果(random.NextDouble()&下; ERRORRATE)
        {
           输入= bad_ preFIX +输入;
        }        int值= 0;
        尝试
        {
            值= Int32.Parse(输入);
        }
        赶上(FormatException)
        {
            值= -1; //我们会在这里做什么用记录仪或许
        }
    }
    stopwatch.Stop();    返回stopwatch.Elapsed;
}///< PARAM NAME =ERRORRATE>年率在用户输入与LT的错误; /参数>
///<退货和GT;采取&LT总时间; /回报>
公共静态时间跨度TimeTryParse(双ERRORRATE,诠释种子,诠释计数)
{
    秒表=新的秒表();
    随机随机=新的随机(种子);
    字符串bad_ preFIX = @X;    stopwatch.Start();
    为(中间体二= 0; II蛋白酶;计数++ⅱ)
    {
        字符串输入= random.Next()的ToString()。
        如果(random.NextDouble()&下; ERRORRATE)
        {
           输入= bad_ preFIX +输入;
        }        int值= 0;
        如果(!Int32.TryParse(输入,超时值))
        {
            值= -1; //我们会在这里做什么用记录仪或许
        }
    }
    stopwatch.Stop();    返回stopwatch.Elapsed;
}公共静态无效TimeStringParse()
{
    双ERRORRATE = 0.1;时间我们的用户搞砸// 10%
    诠释计数= 10000; // 10000项由用户    时间跨度trycatch = TimeTryCatch(ERRORRATE,1,计数);
    时间跨度的TryParse = TimeTryParse(ERRORRATE,1,计数);    Console.WriteLine(trycatch:{0},trycatch);
    Console.WriteLine(的TryParse:{0}的TryParse);
}

I know plenty about the different ways of handling parsing text for information. For parsing integers for example, what kind of performance can be expected. I am wondering if anyone knows of any good stats on this. I am looking for some real numbers from someone who has tested this.

Which of these offers the best performance in which situations?

Parse(...)  // Crash if the case is extremely rare .0001%

If (SomethingIsValid) // Check the value before parsing
    Parse(...)

TryParse(...) // Using TryParse

try
{
    Parse(...)
}
catch
{
    // Catch any thrown exceptions
}

解决方案

Always use T.TryParse(string str, out T value). Throwing exceptions is expensive and should be avoided if you can handle the situation a priori. Using a try-catch block to "save" on performance (because your invalid data rate is low) is an abuse of exception handling at the expense of maintainability and good coding practices. Follow sound software engineering development practices, write your test cases, run your application, THEN benchmark and optimize.

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%" -Donald Knuth

Therefore you assign, arbitrarily like in carbon credits, that the performance of try-catch is worse and that the performance of TryParse is better. Only after we've run our application and determined that we have some sort of slowdown w.r.t. string parsing would we even consider using anything other than TryParse.

(edit: since it appears the questioner wanted timing data to go with good advice, here is the timing data requested)

Times for various failure rates on 10,000 inputs from the user (for the unbelievers):

Failure Rate      Try-Catch          TryParse        Slowdown
  0%           00:00:00.0131758   00:00:00.0120421      0.1
 10%           00:00:00.1540251   00:00:00.0087699     16.6
 20%           00:00:00.2833266   00:00:00.0105229     25.9
 30%           00:00:00.4462866   00:00:00.0091487     47.8
 40%           00:00:00.6951060   00:00:00.0108980     62.8
 50%           00:00:00.7567745   00:00:00.0087065     85.9
 60%           00:00:00.7090449   00:00:00.0083365     84.1
 70%           00:00:00.8179365   00:00:00.0088809     91.1
 80%           00:00:00.9468898   00:00:00.0088562    105.9
 90%           00:00:01.0411393   00:00:00.0081040    127.5
100%           00:00:01.1488157   00:00:00.0078877    144.6


/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryCatch(double errorRate, int seed, int count)
{
    Stopwatch stopwatch = new Stopwatch();
    Random random = new Random(seed);
    string bad_prefix = @"X";

    stopwatch.Start();
    for(int ii = 0; ii < count; ++ii)
    {
        string input = random.Next().ToString();
        if (random.NextDouble() < errorRate)
        {
           input = bad_prefix + input;
        }

        int value = 0;
        try
        {
            value = Int32.Parse(input);
        }
        catch(FormatException)
        {
            value = -1; // we would do something here with a logger perhaps
        }
    }
    stopwatch.Stop();

    return stopwatch.Elapsed;
}

/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryParse(double errorRate, int seed, int count)
{
    Stopwatch stopwatch = new Stopwatch();
    Random random = new Random(seed);
    string bad_prefix = @"X";

    stopwatch.Start();
    for(int ii = 0; ii < count; ++ii)
    {
        string input = random.Next().ToString();
        if (random.NextDouble() < errorRate)
        {
           input = bad_prefix + input;
        }

        int value = 0;
        if (!Int32.TryParse(input, out value))
        {
            value = -1; // we would do something here with a logger perhaps
        }
    }
    stopwatch.Stop();

    return stopwatch.Elapsed;
}

public static void TimeStringParse()
{
    double errorRate = 0.1; // 10% of the time our users mess up
    int count = 10000; // 10000 entries by a user

    TimeSpan trycatch = TimeTryCatch(errorRate, 1, count);
    TimeSpan tryparse = TimeTryParse(errorRate, 1, count);

    Console.WriteLine("trycatch: {0}", trycatch);
    Console.WriteLine("tryparse: {0}", tryparse);
}

这篇关于解析性能(如,的TryParse,尝试捕获)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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