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.

Performance and Benchmarking

68 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 Melbourne Alt.Net on 29th Aug 2017
Code used to generate benchmarks: https://github.com/davidwengier/Benchmark
Recording of the session: https://www.youtube.com/watch?v=S8zhGaT6vv8

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Performance and Benchmarking

  1. 1. PERFORMANCE AND BENCHMARKING David Wengier @ch00k
  2. 2. premature optimization is the root of all evil
  3. 3. premature optimization is the root of all evil - Donald Knuth
  4. 4. 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
  5. 5. “Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. 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
  6. 6. “Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. 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”,
  7. 7. WHEN TO OPTIMIZE? • Optimization is fine when we know we need to • Look at the algorithm before the code • Micro-benchmarking is fine if the code is on the hot path • When experience tells you some things are objectively better • When the better performing code has other benefits
  8. 8. HOW TO OPTIMIZE? • Know the context • Question assumptions • Release builds only • Measure • Measure • Measure
  9. 9. HOW TO OPTIMIZE? public static void Profile(Action func) { DateTime start = DateTime.Now; for (int i = 0; i < 100000; i++) { func(); } Console.WriteLine("Time Elapsed {0} ms", (DateTime.Now - start).TotalMilliseconds); }
  10. 10. HOW TO OPTIMIZE? 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 < 100000; i++) { func(); } watch.Stop(); Console.WriteLine("Time Elapsed {0} ms", watch.Elapsed.TotalMilliseconds); }
  11. 11. BENCHMARKDOTNET (not Benchmark.Net) public class Program { public static void Main(string[] args) { BenchmarkRunner.Run<Program>(); } private string input = "1000"; [Benchmark] public int IntParse() { return int.Parse(input); } [Benchmark] public int ConvertToInt32() { return Convert.ToInt32(input); } }
  12. 12. HOW IT WORKS • Separate process, separate run for each diagnostic. • Pilot: The best operation count will be chosen. • IdleWarmup, IdleTarget: Overhead will be evaluated. • MainWarmup: Warmup of the main method. • MainTarget: Main measurements. • Result = MainTarget – AverageOverhead http://benchmarkdotnet.org/HowItWorks.htm
  13. 13. LETS MICRO BENCHMARK! • NO! • Its too slow.
  14. 14. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  15. 15. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  16. 16. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  17. 17. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  18. 18. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  19. 19. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION
  20. 20. STRING.JOIN VS LINQ VS STRINGBUILDER VS CONCATENATION • Combining 3 x 20 character strings: • StringBuilder: 126ns, 236 b • Concatnation: 267ns, 213 b • Combining 3 x 2,000,000 character strings: • StringBuilder: 122.3 ms, 220 mb • Concatenation: 230.9 ms, 343 mb
  21. 21. DICTIONARY<> VS IDICTIONARY<>
  22. 22. DICTIONARY<> VS IDICTIONARY<> 0 bytes allocated 32 bytes allocated
  23. 23. LOOPS VS LINQ
  24. 24. LOOPS VS LINQ 0 bytes 20 bytes 32 bytes
  25. 25. EXCEPTIONS VS NOT EXCEPTIONS
  26. 26. EXCEPTIONS VS NOT EXCEPTIONS 408 bytes 0 bytes
  27. 27. HYBRIDDICTIONARY 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;
  28. 28. • 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 specify initial capacity on Lists and StringBuilders? Yes. Be nice. SUMMARY

×