c# 4.0 - How to replace chars inorder?? Quickly -
i've got foreach loop replaces char in string in correct order, it's slow..
the input string can have different lengths.. string lengths range 1000 - 1000000
each char takes, 1.2 milliseconds..
but it's input string slows down, anyway replace chars faster..
the charlist char replacements..
i'm replacing chars in input
string value2
charlist items..
list<charitem> charlist; //charlist count = 98.. var txxt = input.tochararray(); string test = ""; foreach (var itm in txxt) { var itm2 = (from x in charlist x.value == itm select x).firstordefault(); if (itm2 != null) test = test + itm2.value2; } public class charitem { public char value { get; set; } public char value2 { get; set; } public override string tostring() { return "1." + value + "| 2." + value2; } }
as statement test = test + itm2.value2;
don't think stringbuilder faster..
anyway speed up, char order needs same, replaced.. know hardware speed limited, optimizing code..
two problems here:
- you recreate string object in each loop step. can use stringbuilder or ienumerable,
- search in charlist has o(n) time complexity, can in o(logn) time if replace list e.g. dictionary.
so i'd suggest code:
list<charitem> charlist; //charlist count = 98.. var replacementrule = charlist.todictionary(item => item.value, item => item.value2); char tempc; return new string(input .select(c => replacementrule.trygetvalue(c, out tempc) ? tempc : (char?) null) .where(c => c != null) .select(c => (char)c) .toarray() );
second way is:
var sb = new stringbuilder();; foreach (var c in input) { char tempc; if (replacementrule.trygetvalue(c, out tempc)) { sb.append(tempc); } } return sb.tostring();
and here're third 1 simple parallelization parallel linq:
const int batchcount = 8; // ~ logical processor count var batchsize = (input.length - 1) / batchcount + 1); var result = enumerable .range(0, batchcount) .select( ind => new { index = ind, stringpart = input.substring( math.min(input.length, batchsize * ind), math.min(batchsize, input.length - math.min(input.length, batchsize * ind)) ) }) .asparallel() .select( batch => new { batch.index, result = replaceinbatch(replacementrule, batch.stringpart) }) .orderby(batch => batch.index) .aggregate(new stringbuilder(input.length), (sb, batch) => sb.append(batch.result)) .tostring(); // .... // somewhere private static stringbuilder replaceinbatch(ireadonlydictionary<char, char> replacementrule, string batch) { var sb = new stringbuilder(); foreach (var c in batch) { char tempc; if (replacementrule.trygetvalue(c, out tempc)) { sb.append(tempc); } } return sb; }
full test console app. replaces lowercase chars uppercase ones.: link
there're 2 revisions both ways - diff can found here: link
there're third revision parallel way.
Comments
Post a Comment