Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pragmatic Performance from NDC London 2019

304 views

Published on

A brief discussion of performance optimization and when to do it, of how to benchmark and use BenchmarkDotNet, and some common gotchas in the .NET framework that you may or may not be aware of.

Presented at NDC London, 30 Jan 2019
Code used to generate benchmarks: https://github.com/davidwengier/Benchmark

Published in: Software
  • Be the first to comment

Pragmatic Performance from NDC London 2019

  1. 1. NDC { London } 2019 David Wengier Microsoft @davidwengier
  2. 2. @davidwengier
  3. 3. - Donald Knuth @davidwengier
  4. 4. - Donald Knuth @davidwengier
  5. 5. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3% - Donald Knuth @davidwengier
  6. 6. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%” - Donald Knuth “Structured Programming with Go To Statements”, 1974@davidwengier
  7. 7. @davidwengier
  8. 8. @davidwengier
  9. 9. @davidwengier
  10. 10. “Don’t do that, that’s slow, and uses too much memory!” @davidwengier
  11. 11. public static void Profile(Action func) { DateTime start = DateTime.Now; for (int i = 0; i < 100; i++) { func(); } Console.WriteLine(“Avg Time Elapsed {0} ms", (DateTime.Now - start).TotalMilliseconds / 100); }
  12. 12. public static void Profile(Action func) { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; func(); Stopwatch watch = new Stopwatch(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); watch.Start(); for (int i = 0; i < 100; i++) { func(); } watch.Stop(); Console.WriteLine(“Avg Time Elapsed {0} ms", watch.Elapsed.TotalMilliseconds / 100); }
  13. 13. https://benchmarkdotnet.org/ https://github.com/dotnet/BenchmarkDotNet • • • • @davidwengier
  14. 14. • • • • • • @davidwengier
  15. 15. • • @davidwengier
  16. 16. • • • • • • • • • @davidwengier
  17. 17. 0 bytes allocated 32 bytes allocated
  18. 18. • • @davidwengier
  19. 19. 0 bytes 20 bytes 32 bytes
  20. 20. • • @davidwengier
  21. 21. • • @davidwengier
  22. 22. public class HybridDictionary: IDictionary { // These numbers have been carefully tested to be optimal. // Please don't change them without doing thorough performance // testing. private const int CutoverPoint = 9;
  23. 23. • Should you always use Dictionary<K,V> instead of IDictionary<K,V>? • Should you always use structs instead of classes? • Should you always use for instead of foreach? • Should you always use StringBuilder instead of concatenation? • Should you always use traditional loops instead of Linq? • Should you always avoid throwing exceptions? @davidwengier
  24. 24. • Should you always use Dictionary<K,V> instead of IDictionary<K,V>? No, it depends. • Should you always use structs instead of classes? No, it depends. • Should you always use for instead of foreach? No, it depends. • Should you always use StringBuilder instead of concatenation? No, it depends. • Should you always use traditional loops instead of Linq? No, it depends. • Should you always avoid throwing exceptions? No, it depends. • Should you always … anything? No, it probably depends. @davidwengier
  25. 25. @davidwengier

×