Performance is a Feature!
-
Upload
postsharp-technologies -
Category
Software
-
view
243 -
download
0
Transcript of Performance is a Feature!
Performance is a Feature!
Performance is a Feature!
Matt Warrenca.com/apm
www.mattwarren.org@matthewwarren
Watch the webinar recording here:
http://www.postsharp.net/blog/post/webinar-recording-performance-is-a-feature
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 moneySave powerBad perf == brokenLost 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 staggering gains made by the computer hardware industry.”
- Henry Petroski
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
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
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
Watch the webinar recording here:
http://www.postsharp.net/blog/post/webinar-recording-performance-is-a-feature
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 bottlenecks2. 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 our performance regressions and omissions.”
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");
[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>();}
Watch the webinar recording here:
http://www.postsharp.net/blog/post/webinar-recording-performance-is-a-feature
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)
BenchmarkDotNetBenchmarkDotNet=v0.9.4.0OS=Microsoft Windows NT 6.1.7601 Service Pack 1Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASEJitModules=clrjit-v4.6.100.0
Type=Program Mode=Throughput
Method | Median | StdDev | Scaled |--------------------- |------------ |----------- |------- | RegularPropertyCall | Reflection |
BenchmarkDotNetBenchmarkDotNet=v0.9.4.0OS=Microsoft Windows NT 6.1.7601 Service Pack 1Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASEJitModules=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 |
[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
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 toolsDapper, Jil, MiniProfiler,
Intimately know your platform - CLR
Roslyn Performance Lessons 1public 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
Roslyn Performance Lessons 1public 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
Roslyn Performance Lessons 2class 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); }}
Roslyn Performance Lessons 2class 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
BenchmarkDotNetBenchmarkDotNet=v0.9.4.0OS=Microsoft Windows NT 6.1.7601 Service Pack 1Processor=Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz, ProcessorCount=8Frequency=2630654 ticks, Resolution=380.1336 ns, Timer=TSCHostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASEJitModules=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 |
Roslyn Performance Lessons 3public 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(); }}
Roslyn Performance Lessons 3public 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
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;}
Questions?
@matthewwarren
www.mattwarren.org
Watch the webinar recording here:
http://www.postsharp.net/blog/post/webinar-recording-performance-is-a-feature