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 is a Feature!
Performance is a Feature!
Matt Warren
ca.com/apm
www.mattwarren.org
@matthewwarren
Front-end
Database & Caching
.NET CLR
Mechanical
Sympathy
Why does performance matter?
What do we need to measure?
How we can fix the issues?
Why?
Save money
Save power
Bad perf == broken
Lost customers
Half a second delay caused
a 20% drop in traffic
(Google)
Why?
“The most amazing achievement of
the computer software industry is its
continuing cancellation of the steady
and stag...
Why?
“We should forget about small efficiencies,
say about 97% of the time: premature
optimization is the root of all evil...
Why?
“We should forget about small efficiencies,
say about 97% of the time: premature
optimization is the root of all evil...
Never give up your
performance accidentally
Rico Mariani,
Performance Architect @
Microsoft
What?
Averages
are bad
"most people have
more than the average
number of legs"
- Hans Rosling
https://www.ted.com/talks/hans_rosling_shows_the_best_stats_you_ve_ever_seen
https://blogs.msdn.microsoft.com/bharry/2016/03/28/introducing-application-analytics/
Application Insights Analytics
When?
In production
You won't see ANY perf issues
during unit tests
You won't see ALL perf issues
in Development
How?
Measure, measure, measure
1. Identify bottlenecks
2. Verify the optimisation works
How?
“The simple act of putting a render time in the upper right hand corner of every
page we serve forced us to fix all o...
How?
https://github.com/opserver/Opserver
How?
https://github.com/opserver/Opserver
How?
Micro-benchmarks
How?
Profiling -> Micro-benchmarks
http://www.hanselman.com/blog/BenchmarkingNETCode.aspx
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
static Uri @object = new Uri("http://google.com/search");...
Compared to one second
• Millisecond – ms
–thousandth (0.001 or 1/1000)
• Microsecond - μs
–millionth (0.000001 or 1/1,000...
BenchmarkDotNet
BenchmarkDotNet=v0.9.4.0
OS=Microsoft Windows NT 6.1.7601 Service Pack 1
Processor=Intel(R) Core(TM) i7-48...
BenchmarkDotNet
BenchmarkDotNet=v0.9.4.0
OS=Microsoft Windows NT 6.1.7601 Service Pack 1
Processor=Intel(R) Core(TM) i7-48...
[Params(1, 2, 3, 4, 5, 10, 100, 1000)]
public int Loops;
[Benchmark]
public string StringConcat()
{
string result = string...
How?
Garbage Collection (GC)
Allocations are cheap, but cleaning up isn’t
Difficult to measure the impact of GC
https://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our-
recent-battles-with-the-net-garbage-collector
Stack Overflow Performance Lessons
Use static classes
Don’t be afraid to write your own tools
Dapper, Jil, MiniProfiler,
I...
Roslyn Performance Lessons 1
public class Logger
{
public static void WriteLine(string s) { /*...*/ }
}
public class Logge...
Roslyn Performance Lessons 1
public class Logger
{
public static void WriteLine(string s) { /*...*/ }
}
public class Boxin...
Roslyn Performance Lessons 2
class Symbol {
public string Name { get; private set; }
/*...*/
}
class Compiler {
private Li...
Roslyn Performance Lessons 2
class Symbol {
public string Name { get; private set; }
/*...*/
}
class Compiler {
private Li...
BenchmarkDotNet
BenchmarkDotNet=v0.9.4.0
OS=Microsoft Windows NT 6.1.7601 Service Pack 1
Processor=Intel(R) Core(TM) i7-48...
Roslyn Performance Lessons 3
public class Example
{
// Constructs a name like "Foo<T1, T2, T3>"
public string GenerateFull...
Roslyn Performance Lessons 3
public class Example
{
// Constructs a name like "Foo<T1, T2, T3>"
public string GenerateFull...
Roslyn Performance Lessons 3
[ThreadStatic]
private static StringBuilder cachedStringBuilder;
private static StringBuilder...
Questions?
www.oz-code.com
@matthewwarren www.mattwarren.org
jetbrains.com/dotTrace
jetbrains.com/dotMemory
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Performance is a Feature! at DDD 11
Upcoming SlideShare
Loading in …5
×

Performance is a Feature! at DDD 11

656 views

Published on

Starting with the premise that "Performance is a Feature", this session will look at how to measure, what to measure and how get the best performance from your .NET code.

We will look at real-world examples from the Roslyn code-base and StackOverflow (the product), including how the .NET Garbage Collector needs to be tamed!

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Performance is a Feature! at DDD 11

  1. 1. Performance is a Feature!
  2. 2. Performance is a Feature! Matt Warren ca.com/apm www.mattwarren.org @matthewwarren
  3. 3. Front-end Database & Caching .NET CLR Mechanical Sympathy
  4. 4. Why does performance matter? What do we need to measure? How we can fix the issues?
  5. 5. Why? Save money Save power Bad perf == broken Lost customers Half a second delay caused a 20% drop in traffic (Google)
  6. 6. Why? “The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry.” - Henry Petroski
  7. 7. Why? “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
  8. 8. Why? “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
  9. 9. Never give up your performance accidentally Rico Mariani, Performance Architect @ Microsoft
  10. 10. What? Averages are bad
  11. 11. "most people have more than the average number of legs" - Hans Rosling
  12. 12. https://www.ted.com/talks/hans_rosling_shows_the_best_stats_you_ve_ever_seen
  13. 13. https://blogs.msdn.microsoft.com/bharry/2016/03/28/introducing-application-analytics/ Application Insights Analytics
  14. 14. When? In production You won't see ANY perf issues during unit tests You won't see ALL perf issues in Development
  15. 15. How? Measure, measure, measure 1. Identify bottlenecks 2. Verify the optimisation works
  16. 16. How? “The simple act of putting a render time in the upper right hand corner of every page we serve forced us to fix all our performance regressions and omissions.”
  17. 17. How? https://github.com/opserver/Opserver
  18. 18. How? https://github.com/opserver/Opserver
  19. 19. How? Micro-benchmarks
  20. 20. How? Profiling -> Micro-benchmarks
  21. 21. http://www.hanselman.com/blog/BenchmarkingNETCode.aspx
  22. 22. using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; static Uri @object = new Uri("http://google.com/search"); [Benchmark(Baseline = true)] public string RegularPropertyCall() { return @object.Host; } [Benchmark] public object Reflection() { Type @class = @object.GetType(); PropertyInfo property = @class.GetProperty(propertyName, bindingFlags); return property.GetValue(@object); } static void Main(string[] args) { var summary = BenchmarkRunner.Run<Program>(); }
  23. 23. Compared to one second • Millisecond – ms –thousandth (0.001 or 1/1000) • Microsecond - μs –millionth (0.000001 or 1/1,000,000) • Nanosecond - ns –billionth (0.000000001 or 1/1,000,000,000)
  24. 24. BenchmarkDotNet BenchmarkDotNet=v0.9.4.0 OS=Microsoft Windows NT 6.1.7601 Service Pack 1 Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8 HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE JitModules=clrjit-v4.6.100.0 Type=Program Mode=Throughput Method | Median | StdDev | Scaled | --------------------- |------------ |----------- |------- | RegularPropertyCall | Reflection |
  25. 25. BenchmarkDotNet BenchmarkDotNet=v0.9.4.0 OS=Microsoft Windows NT 6.1.7601 Service Pack 1 Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8 HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE JitModules=clrjit-v4.6.100.0 Type=Program Mode=Throughput Method | Median | StdDev | Scaled | --------------------- |------------ |----------- |------- | RegularPropertyCall | 13.4053 ns | 1.5826 ns | 1.00 | Reflection | 232.7240 ns | 32.0018 ns | 17.36 |
  26. 26. [Params(1, 2, 3, 4, 5, 10, 100, 1000)] public int Loops; [Benchmark] public string StringConcat() { string result = string.Empty; for (int i = 0; i < Loops; ++i) result = string.Concat(result, i.ToString()); return result; } [Benchmark] public string StringBuilder() { StringBuilder sb = new StringBuilder(string.Empty); for (int i = 0; i < Loops; ++i) sb.Append(i.ToString()); return sb.ToString(); } https://github.com/dotnet/roslyn/issues/5388
  27. 27. How? Garbage Collection (GC) Allocations are cheap, but cleaning up isn’t Difficult to measure the impact of GC
  28. 28. https://samsaffron.com/archive/2011/10/28/in-managed-code-we-trust-our- recent-battles-with-the-net-garbage-collector
  29. 29. Stack Overflow Performance Lessons Use static classes Don’t be afraid to write your own tools Dapper, Jil, MiniProfiler, Intimately know your platform - CLR
  30. 30. Roslyn Performance Lessons 1 public class Logger { public static void WriteLine(string s) { /*...*/ } } public class Logger { public void Log(int id, int size) { var s = string.Format("{0}:{1}", id, size); Logger.WriteLine(s); } } Essential Truths Everyone Should Know about Performance in a Large Managed Codebase http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B333
  31. 31. Roslyn Performance Lessons 1 public class Logger { public static void WriteLine(string s) { /*...*/ } } public class BoxingExample { public void Log(int id, int size) { var s = string.Format("{0}:{1}", id.ToString(), size.ToString()); Logger.WriteLine(s); } } https://github.com/dotnet/roslyn/pull/415 AVOID BOXING
  32. 32. Roslyn Performance Lessons 2 class Symbol { public string Name { get; private set; } /*...*/ } class Compiler { private List<Symbol> symbols; public Symbol FindMatchingSymbol(string name) { return symbols.FirstOrDefault(s => s.Name == name); } }
  33. 33. Roslyn Performance Lessons 2 class Symbol { public string Name { get; private set; } /*...*/ } class Compiler { private List<Symbol> symbols; public Symbol FindMatchingSymbol(string name) { foreach (Symbol s in symbols) { if (s.Name == name) return s; } return null; } } DON’T USE LINQ
  34. 34. BenchmarkDotNet BenchmarkDotNet=v0.9.4.0 OS=Microsoft Windows NT 6.1.7601 Service Pack 1 Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8 Frequency=2630654 ticks, Resolution=380.1336 ns, Timer=TSC HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE JitModules=clrjit-v4.6.100.0 Type=Program Mode=Throughput Runtime=Clr Method | Median | StdDev | Gen 0 | Bytes Allocated/Op | ---------- |----------- |---------- |------- |------------------- | Iterative | 39.0957 ns | 0.2150 ns | - | 0.00 | LINQ | 53.2441 ns | 0.5385 ns | 701.50 | 23.21 |
  35. 35. Roslyn Performance Lessons 3 public class Example { // Constructs a name like "Foo<T1, T2, T3>" public string GenerateFullTypeName(string name, int arity) { StringBuilder sb = new StringBuilder(); sb.Append(name); if (arity != 0) { sb.Append("<"); for (int i = 1; i < arity; i++) { sb.Append('T'); sb.Append(i.ToString()); } sb.Append('T'); sb.Append(arity.ToString()); } return sb.ToString(); } }
  36. 36. Roslyn Performance Lessons 3 public class Example { // Constructs a name like "Foo<T1, T2, T3>" public string GenerateFullTypeName(string name, int arity) { StringBuilder sb = new AcquireBuilder(); sb.Append(name); if (arity != 0) { sb.Append("<"); for (int i = 1; i < arity; i++) { sb.Append('T'); sb.Append(i.ToString()); } sb.Append('T'); sb.Append(arity.ToString()); } return GetStringAndReleaseBuilder(sb); } } OBJECT POOLING
  37. 37. Roslyn Performance Lessons 3 [ThreadStatic] private static StringBuilder cachedStringBuilder; private static StringBuilder AcquireBuilder() { StringBuilder result = cachedStringBuilder; if (result == null) { return new StringBuilder(); } result.Clear(); cachedStringBuilder = null; return result; } private static string GetStringAndReleaseBuilder(StringBuilder sb) { string result = sb.ToString(); cachedStringBuilder = sb; return result; }
  38. 38. Questions? www.oz-code.com @matthewwarren www.mattwarren.org jetbrains.com/dotTrace jetbrains.com/dotMemory

×