c#-如果,否则是否与映射性能

我有一个性能问题.

我正在解析大型文本文件(票据),并根据帐单上是否显示某些文本,将服务提供商的名称分配给变量.

这只是我正在做的一小部分(不要笑,我知道那很乱).总共大约有250个if,否则为if.

if (txtvar.BillText.IndexOf("SWGAS.COM") > -1)
   {
       txtvar.Provider = "Southwest Gas";
   }
else if (txtvar.BillText.IndexOf("georgiapower.com") > -1)
   {
       txtvar.Provider = "Georgia Power";
   }
else if (txtvar.BillText.IndexOf("City of Austin") > -1)
   {
       txtvar.Provider = "City of Austin";
   }

//依此类推250次

因为它变得如此之大,所以我决定采用另一种方法来更清洁,更高效.我最终实现了一个映射,并将其存储在外部.psv文件中.

我将该映射保存到一个变量中(该变量只运行一次,大约需要35毫秒…

var providerMap =
                    System.IO.File.ReadLines(@"U:\Program\ApplicationFiles\ProvidersList.psv")
                    .Select(line => line.Split('|'))
                    .Select(parts => new Provider() { Pattern = parts[0], Name = parts[1] }).ToList();

…然后遍历每个账单(分配提供者大约需要2毫秒,而if语句花费的时间不到一半.

foreach (string bills in files)
                                {
                                    string Provider = providerMap.First(p => txtvar.BillText.IndexOf(p.Pattern) > -1).Name;
                                    OtherStuff();
                                }

尽管此解决方案更加简洁,但令人惊讶的是,如果不是,则比250慢得多.我使用秒表方法发现,更清洁的方法实际上是数百条if语句速度的两倍. (我测试了在if语句的开头和结尾处的帐单,并以相似的结果进行映射)

有人可以向我解释吗?也许我做错了什么?谢谢!

解决方法:

循环展开是一种通过将循环转换为语句序列来提高性能的技术.一个简单的例子

for(int i = 0; i < 3; i++)
{
    Console.WriteLine(i);
}

可以展开到

Console.WriteLine(0);
Console.WriteLine(1);
Console.WriteLine(2);

有各种各样复杂的技术可以执行此操作,但要点是要减少机器码中循环变量,条件的求值和跳转指令的增量数量.请注意,此技术并不总是可以降低性能.有关更多讨论和示例,请参见loop unwinding.

你走了另一条路.您已经使用了很长的if-else构造并将其转换为

string Provider = providerMap.First(p => txtvar.BillText.IndexOf(p.Pattern) > -1).Name;

现在,First所做的实际上就是这样做(请注意,如果没有项目匹配,则First会抛出该错误):

Provider found = null;
foreach(var provider in providerMap)
{
    if (txtvar.BillText.IndexOf(provider.Pattern) > -1)
    {
        found = provider;
        break;
    }
}

因此,您可以看到相反的方式:从一系列语句到循环.

我认为您已经获得了一些您没有提到的功能,即无需重新编译代码即可添加提供程序的功能,这很方便.

上一篇:Elasticsearch基本数据类型与设置


下一篇:java-mappingBy是指类名还是表名?