Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Writing Faster Managed Code

Writing Faster Managed Code

Scheduled Pinned Locked Moved C#
csharpc++htmldotnetcom
2 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MtnBiknGuy
    wrote on last edited by
    #1

    Jan Gray of the Microsoft CLR Performance Team wrote an excellent article titled "Writing Faster Managed Code: Know What Things Cost" (http://msdn.microsoft.com/library/?url=/library/en-us/dndotnet/html/fastmanagedcode.asp). This article has motivated me to seek answers to the following questions. Any replies from the group are appreciated. The questions probably (hopefully) have very simple answers. Between these two foreach loops, is there any difference in performance, safety or correctness? (All examples are in C#) 1. declare and initialize new type in body of loop: foreach (T t in tList) { A a = new A(t.ID); //do more work myCollection.Add(a); } 2. declare new type outside loop, and 'new' it inside loop: A a = null; foreach (T t in tList) { a = new A(t.ID); //do more work myCollection.Add(a); } I would think #2 is preferrable, but I see that most C# examples use the style of #1. In fact, I often see the following in C# examples: T MyMethod() { T t = new T(); return t; } This would be a big problem in C++, but in C# the garbage collector makes it OK. But does that mean it's a good practice? Why is it so common in examples? Finally, I'm curious if there are any performance differences between the following two loops. The reason I ask is that I'm one of those people who (prior to reading the above mentioned article) pulled the array.Length property out of the loop header in the interest of avoiding extra calls to get the length value. I now understand why that is not optimal. I'm curious if any processor optimizations or compiler optimizations make choice 1 equal to or better than choice 2 below: 1. repeat same property calls inside a loop: for (int i = 0; i < 10; ++i) { DoAlgorithm1(i, T.x); DoAlgorithm2(i, T.x + y); DoAlgorithm3(i, T.x + y); } 2. pull property calls outside the loop: double x = T.x; double w = x + y; for (int i = 0; i < 10; ++i) { DoAlgorithm1(i, x); DoAlgorithm2(i, w); DoAlgorithm3(i, w); } All input is appreciated!

    D 1 Reply Last reply
    0
    • M MtnBiknGuy

      Jan Gray of the Microsoft CLR Performance Team wrote an excellent article titled "Writing Faster Managed Code: Know What Things Cost" (http://msdn.microsoft.com/library/?url=/library/en-us/dndotnet/html/fastmanagedcode.asp). This article has motivated me to seek answers to the following questions. Any replies from the group are appreciated. The questions probably (hopefully) have very simple answers. Between these two foreach loops, is there any difference in performance, safety or correctness? (All examples are in C#) 1. declare and initialize new type in body of loop: foreach (T t in tList) { A a = new A(t.ID); //do more work myCollection.Add(a); } 2. declare new type outside loop, and 'new' it inside loop: A a = null; foreach (T t in tList) { a = new A(t.ID); //do more work myCollection.Add(a); } I would think #2 is preferrable, but I see that most C# examples use the style of #1. In fact, I often see the following in C# examples: T MyMethod() { T t = new T(); return t; } This would be a big problem in C++, but in C# the garbage collector makes it OK. But does that mean it's a good practice? Why is it so common in examples? Finally, I'm curious if there are any performance differences between the following two loops. The reason I ask is that I'm one of those people who (prior to reading the above mentioned article) pulled the array.Length property out of the loop header in the interest of avoiding extra calls to get the length value. I now understand why that is not optimal. I'm curious if any processor optimizations or compiler optimizations make choice 1 equal to or better than choice 2 below: 1. repeat same property calls inside a loop: for (int i = 0; i < 10; ++i) { DoAlgorithm1(i, T.x); DoAlgorithm2(i, T.x + y); DoAlgorithm3(i, T.x + y); } 2. pull property calls outside the loop: double x = T.x; double w = x + y; for (int i = 0; i < 10; ++i) { DoAlgorithm1(i, x); DoAlgorithm2(i, w); DoAlgorithm3(i, w); } All input is appreciated!

      D Offline
      D Offline
      Daniel Turini
      wrote on last edited by
      #2

      Optimization is fun, but not easy... Not a single concept is always true. Combine this with multi-threading (think about the SMP machines and the newer hyperthreading processors) and optimization is almost a try and guess game, although some basic techniques do help a bit. MtnBiknGuy wrote: I would think #2 is preferrable, but I see that most C# examples use the style of #1. In fact, I often see the following in C# examples: #2 does one inutile assignment, #1 don't. But to solve this doubt, remove the "= null" (BTW, this isn't a good practice, as it defeats some useful compiler warnings) and just look and the generated code with ILDASM. I bet they generate exactly the same IL, as the maximum stack space is allocated on the method's entry. MtnBiknGuy wrote: Finally, I'm curious if there are any performance differences between the following two loops. If the JIT is as good as MS sells it, #1 could even be slightly faster than #2. MS says JIT does common subexpression elimination and code motion of loop invariants, which is exactly what you did, but sometimes the JIT could even do it without the need for another local variable (imagine that you have several loops). Notice that the JIT sometimes will do a better job than you. If T.x is a virtual property, and not a field, you can't safely do what you showed (T.x could have a side effect, e.g. incrementing a counter to keep usage count). Although sometimes the JIT hasn't all the info or time it needs to make all the possible optimizations, it has all the info it needs to always act safely. On a side note, you should make all of your timings on Release builds, because the optimizer is disabled on the Debug builds. Kant wrote: Actually she replied back to me "You shouldn't fix the bug. You should kill it"

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups