c# - if, else if vs. mapping performance -
i have performance question.
i parsing large text files (bills) , assigning name of service provider variable based on if text appears on bill.
this small sample of doing (don't laugh, know it's messy). in all, there approximately 250 if, else if's.
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"; }
// , on , forth 250 times
because grew big decided take different approach cleaner , more efficient. ended implementing mapping, store in external .psv file.
i save mapping variable (this runs once , takes 35 milliseconds...
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();
...and loop through each bill (assigning provider takes 2 milliseconds while if statements took less half time....
foreach (string bills in files) { string provider = providermap.first(p => txtvar.billtext.indexof(p.pattern) > -1).name; otherstuff(); }
while solution cleaner, it's surprisingly lot slower 250+ if, else if's. used stopwatch method find out cleaner method twice slow hundreds of if statements. (i tested bills towards beginning , end of if statements , mapping similar results)
can explain me? maybe i'm doing wrong? thanks!
loop unrolling technique improving performance translating loop sequence of statements. trivial example
for(int = 0; < 3; i++) { console.writeline(i); }
could unrolled
console.writeline(0); console.writeline(1); console.writeline(2);
there sorts of sophisticated techniques doing this, point reduce number of increments loop variable, evaluations of conditional, , jump instructions in machine code. note technique not hand-downs performance gain. see loop unwinding more discussion , examples.
you have gone other way. you've taken long if-else
construct , turned into
string provider = providermap.first(p => txtvar.billtext.indexof(p.pattern) > -1).name;
now first
doing (note first
throw in case no item matches):
provider found = null; foreach(var provider in providermap) { if (txtvar.billtext.indexof(provider.pattern) > -1) { found = provider; break; } }
so can see you've gone opposite way: sequence of statements loop.
i think you've gained haven't mentioned ability add providers without recompiling code, can handy.
Comments
Post a Comment