如果,否则如果与映射性能
本文关键字:如果 映射 性能 | 更新日期: 2023-09-27 18:32:47
我有一个性能问题。
我正在解析大型文本文件(账单(,并根据账单上是否出现某些文本将服务提供商的名称分配给变量。
这是我正在做的事情的一小部分样本(不要笑,我知道这很混乱(。总而言之,大约有 250 个如果,否则如果。
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 的。我使用秒表方法发现,更清洁的方法实际上比数百个if语句慢两倍。(我测试了 if 语句开头和结尾的账单,结果相似(
谁能向我解释一下?也许我做错了什么?谢谢!
读取外部文件肯定会减慢您的速度。我假设你只读了一次,但它仍然会减慢你的速度。
1(您是否尝试过缓存文件的内容,以便无需再次阅读?如果映射变化不大,这可能是一个改进。
2(另外,为什么不尝试将映射存储在字典对象(或类似结构(中?如果您愿意,可以将其放在单独的类文件中。这是一个硬编码的解决方案,不确定它在您的系统中的运行情况如何。
循环展开是一种通过将循环转换为语句序列来提高性能的技术。一个微不足道的例子
for(int i = 0; i < 3; i++)
{
Console.WriteLine(i);
}
可以展开到
Console.WriteLine(0);
Console.WriteLine(1);
Console.WriteLine(2);
有各种各样的复杂技术可以做到这一点,但关键是你减少了循环变量的增量数量、条件的计算和机器代码中的跳转指令。请注意,此技术并不总是降低性能。有关更多讨论和示例,请参阅循环展开。
你走了另一条路。你花了很长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;
}
}
所以你可以看到你走了相反的道路:从一系列语句到循环。
我认为您已经获得了一些您没有提到的东西,即无需重新编译代码即可添加提供程序的能力,这可能很方便。
我会选择第三个选项,
1-更具可读性
2-更少的代码,也可以是性能+1。
3-更易于维护
4-DLL内部没有字符串,这也减小了DLL的大小