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

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -