performance is a feature! - developer south coast - part 2

29
Performance is a Feature!

Upload: matt-warren

Post on 07-Aug-2015

77 views

Category:

Technology


0 download

TRANSCRIPT

Performance is a Feature!

Why does performance matter?

What do we need to measure?

How we can fix the issues?

Front-end

Database & Caching

.NET CLR

Mechanical Sympathy

How?

Measure, measure, measure

1. Identify bottlenecks2. Know 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?

The Art of Benchmarking

Profiling -> Micro-benchmarks

static void Profile(int iterations, Action action) {

action(); // warm up GC.Collect(); // clean up

var watch = new Stopwatch(); watch.Start(); for (int i = 0; i < iterations; i++) { action(); } watch.Stop();

Console.WriteLine("Time Elapsed {0} ms", watch.ElapsedMilliseconds);

}

http://stackoverflow.com/questions/1047218/benchmarking-small-code-samples-in-c-can-this-implementation-be-improved

private static T Result;static void Profile<T>(int iterations, Func<T> func) {

func(); // warm up GC.Collect(); // clean up

var watch = new Stopwatch(); watch.Start(); for (int i = 0; i < iterations; i++) { Result = func(); } watch.Stop();

Console.WriteLine("Time Elapsed {0} ms", watch.ElapsedMilliseconds);

}

BenchmarkDotNet

BenchmarkDotNet Demo

How?

Garbage Collection (GC)

Allocations are cheap, but cleaning up isn’t

Difficult to measure the impact of GC

http://www.slideshare.net/benemmett/net-memory-management-ndc-london https://vimeo.com/113632451

Stack Overflow Performance Lessons

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 BoxingExample{ 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

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); }} 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

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;}

Roslyn Performance Lessons Demo

Resources

Questions?

@matthewwarren

www.mattwarren.org