解析性能(If、TryParse、Try-Catch) [英] Parsing Performance (If, TryParse, Try-Catch)

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

问题描述

我非常了解处理信息解析文本的不同方法.例如,对于解析整数,可以预期什么样的性能.我想知道是否有人知道这方面的任何好的统计数据.我正在从测试过这个的人那里寻找一些真实的数字.

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
}

推荐答案

总是使用T.TryParse(string str, out T value).抛出异常代价高昂,如果您可以先验处理这种情况,就应该避免.使用 try-catch 块来节省"性能(因为您的无效数据率很低)是对异常处理的滥用,以牺牲可维护性和良好的编码实践为代价.遵循良好的软件工程开发实践,编写测试用例,运行应用,然后进行基准测试和优化.

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.

我们应该忘记小效率,比如大约 97% 的时间:过早的优化是万恶之源.但我们不应该在关键的 3% 中放弃我们的机会"-唐纳德·克努斯

"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

因此,您可以像在碳信用额中那样任意指定 try-catch 的性能更差,而 TryParse 的性能更好.只有在我们运行我们的应用程序并确定我们有某种减速 w.r.t.字符串解析我们甚至会考虑使用 TryParse 以外的任何东西.

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.

(由于提问者似乎希望时间数据与好的建议一起使用,这里是请求的时间数据)

来自用户的 10,000 次输入的各种失败率的次数(对于非信徒):

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

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

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