c# - Forward/Backward loop performance analysis -


i've been investigating performance issues event viewer application have on our development site when noticed interesting issue in algorithm. created simplified test project test 2 different algorithms. program retrieves windows event logs using eventlog class, , translates logs queryable eventlogitem entities.

this operation performed , timed using 2 different loops. first (backward) loop starts @ index of last item in list, translates item , decreases index. method defined this:

private static void translatelogsusingbackwardloop() {     stopwatch stopwatch = new stopwatch();     stopwatch.start();      var originallogs = eventlog.geteventlogs();     var translatedlogs = new list<eventlogitem>();      parallel.foreach<eventlog>(originallogs, currentlog =>     {         (int index = currentlog.entries.count - 1; index >= 0; index--)         {             var currententry = currentlog.entries[index];              eventlogitem translatedentry = new eventlogitem             {                 machinename = currententry.machinename,                 logname = currentlog.logdisplayname,                 createdtime = currententry.timegenerated,                 source = currententry.source,                 message = currententry.message,                 number = currententry.index,                 category = currententry.category,                 type = currententry.entrytype,                 instanceid = currententry.instanceid,                 user = currententry.username,             };              lock (translatedlogs)             {                 translatedlogs.add(translatedentry);             }         }     });      stopwatch.stop();      console.writeline("{0} logs translated in {1} using backward loop.", translatedlogs.count, stopwatch.elapsed); } 

the second (forward) loop starts @ index 0 , increments index. method defined this:

private static void translatelogsusingforwardloop() {     stopwatch stopwatch = new stopwatch();     stopwatch.start();      var originallogs = eventlog.geteventlogs();     var translatedlogs = new list<eventlogitem>();      parallel.foreach<eventlog>(originallogs, currentlog =>     {         (int index = 0; index < currentlog.entries.count; index++)         {             var currententry = currentlog.entries[index];              eventlogitem translatedentry = new eventlogitem             {                 machinename = currententry.machinename,                 logname = currentlog.logdisplayname,                 createdtime = currententry.timegenerated,                 source = currententry.source,                 message = currententry.message,                 number = currententry.index,                 category = currententry.category,                 type = currententry.entrytype,                 instanceid = currententry.instanceid,                 user = currententry.username,             };              lock (translatedlogs)             {                 translatedlogs.add(translatedentry);             }         }     });      stopwatch.stop();      console.writeline("{0} logs translated in {1} using forward loop.", translatedlogs.count, stopwatch.elapsed); } 

and main method:

static void main(string[] args) {     translatelogsusingforwardloop();     console.writeline();     thread.sleep(2000);     translatelogsusingbackwardloop();     console.readline(); } 

this (performed test several times, , results identical):

enter image description here

note server tested on logs event log every second, that's why number of translated logs not same. why backward loop faster? thought it's because in backward loop algorithm, currentlog.entries.count evaluated once, in forward loop needs calculated , compared against index on every loop iteration, again doesn't seem right. ideas?

testing againt 0 versus maxndex have little effect. however, performing test1 test2 shortly thereafter has effect due processor caching and/or o/s page caching. might reverse test1/test2 see if forwards magically becomes faster backwards. accurate profiling hard on modern achitectures.

ok, backwards still faster when executed first. not first guess, since using parallel , lock, there perhaps interaction between locking method , difference between forward , backward looping.

maybe backwards loop happens work better processor branch prediction (again may interact parallism, processor cache, etc.).

lots of tight loops in multi-thread code have weird interactions memory management because of locking overhead. -- not uncommon multi-thread solution slower because of lock contention

you can try running without parallel both forward , see if time becomes more -- @ best determine / unlikely relation parallel interactions or lock contention. profiling code may suggestive, may may not procide definite answer either. definitive answer can quite difficult situation (i assumed in curious/learning mode).


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -