Memory Management, C# 7.2 and Span<T>

A presentation at .NET South West in September 2018 in by Stuart Lang

Slide 1

Slide 1

Memory Management, C# 7.2 and Span<T>

Slide 2

Slide 2

HELLO! F# |> I ❤ 9 years of experience in .NET Organiser of Bristol F# meetup and DDD South West You can find me at @stuartblang & https://stu.dev

Slide 3

Slide 3

Slide 4

Slide 4

Rust

Slide 5

Slide 5

● FAST ● SAFE ● MAINTAINABLE Can C# have all 3?

Slide 6

Slide 6

C# as a high performance language

Slide 7

Slide 7

C# as a high performance language

Slide 8

Slide 8

Performance where it matters Fr am ew or ks Li br ar ie s

Slide 9

Slide 9

Always Measure

Slide 10

Slide 10

Measure with… ▸ ▸ ▸ ▸ Memory Performance Counters BenchmarkDotNet dotMemory Visual Studio

Slide 11

Slide 11

How it works

Slide 12

Slide 12

Slide 13

Slide 13

Slide 14

Slide 14

“ The Stack Is An Implementation Detail. - Eric Lippert Part One Part Two

Slide 15

Slide 15

Types ▸ Value types ▹ Structs ▹ Enums ▹ Bool ▹ Int, Float, Short, Long… ▹ Byte ▸ Reference types ▹ Class ▹ Interface ▹ Array ▹ String ▹ Delegate

Slide 16

Slide 16

Stack Code sharplab.io demo a=42 Stack Heap x(ref) object: array{1,2,3}

Slide 17

Slide 17

Code - behaviour

Slide 18

Slide 18

Stack Credit: http://www.i-programmer.info/ebooks/deep-c/363

Slide 19

Slide 19

Heap Small Object Heap Gen 0 Gen 1 Large Object Heap Gen 2

Slide 20

Slide 20

Heap Credit: https://www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/

Slide 21

Slide 21

Great Resource ▸ http://benhall.io/a-super-simplified-exp lanation-of-net-garbage-collection/

Slide 22

Slide 22

Stack vs Heap What? Lifetime When disposed? Time to dispose Stack Local values Local references (just the ref part) Stack frame Deterministic Constant (near instant) Heap Reference object instances Unrestricted GC non-deterministic It depends (non-trivial)

Slide 23

Slide 23

Watch out for hidden allocations ▸ Let’s see some examples

Slide 24

Slide 24

Watch out for hidden allocations

Slide 25

Slide 25

Watch out for hidden allocations

Slide 26

Slide 26

Watch out for hidden allocations

Slide 27

Slide 27

Watch out for hidden allocations

Slide 28

Slide 28

Plugins ▸ R# Heap Allocations Viewer ▸ Roslyn Clr Heap Allocation Analyzer

Slide 29

Slide 29

Slide 30

Slide 30

In Parameters

Slide 31

Slide 31

In Parameters - cont. ▸ Essentially readonly ref ▸ Where you want to want to pass by-ref for performance, with the safety and behaviour or by-value ▸ Watch out for copying with invoking methods on non-readonly structs

Slide 32

Slide 32

Ref extension methods

Slide 33

Slide 33

Ref locals ▸ Reference semantics with value types

Slide 34

Slide 34

Ref locals ▸ Can be thought of as aliases

Slide 35

Slide 35

Ref returns

Slide 36

Slide 36

Ref Struct ▸ Aka ref-like ▸ Stack-only! ▸ To support Span<T>

Slide 37

Slide 37

Ref Struct

Slide 38

Slide 38

“ The great Eric Lippert once wrote “The Stack Is An Implementation Detail”, and basically that’s not true anymore. - Jon Skeet

Slide 39

Slide 39

Span<T> ▸ Abstraction over arbitrary memory Span<T> Marshal.AllocHGlobal() stackalloc [] new []

Slide 40

Slide 40

Span<T>

Slide 41

Slide 41

Span<T>

Slide 42

Slide 42

Span<T> - Why stack-only? ▸ Safe lifetime - cannot outlive stack memory ▸ Safe concurrency - No struct tearing ▸ It’s fast!

Slide 43

Slide 43

Span<T> - Other properties ▸ Efficient representation ▸ GC tracking - refs will be maintained by GC

Slide 44

Slide 44

Use Cases ▸ Alternative to unsafe code ▸ Parsing text ▸ Sharing partial parts of memory

Slide 45

Slide 45

Problem with pointers ▸ ▸ ▸ ▸ Requires GC pinning (for heap memory) Mustn’t escape pointer (for stack) No bounds checking Unsafe code blocks

Slide 46

Slide 46

Problem with pointers

Slide 47

Slide 47

Credit: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/stackalloc

Slide 48

Slide 48

Slide 49

Slide 49

You can still pin

Slide 50

Slide 50

You can still pin - in C# 7.3

Slide 51

Slide 51

BenchmarkDotNet

Slide 52

Slide 52

Slide 53

Slide 53

Slide 54

Slide 54

Results

Slide 55

Slide 55

C# 8 - Slicing with Ranges demo

Slide 56

Slide 56

Slide 57

Slide 57

Slide 58

Slide 58

Span<T> Framework APIs Today netcoreapp2.0 ❌ netcoreapp2.1 ✅ netstandard2.0 ❌ Next netcoreapp2.2 ✅ netcoreapp2.3 ✅ netcoreapp3.0 ✅ netstandard2.1 ✅ ❓ net472 ❌ net48 ❌ net49 ❓

Slide 59

Slide 59

Related topics ▸ ReadOnlySpan<T> ▸ Memory<T> & ReadOnlyMemory<T> ▸ System.Runtime.CompilerServices.Unsafe ▸ MemoryMarshal.AsBytes(span) ▸ MemoryMarshal.Cast<TFrom,TTo>(span)

Slide 60

Slide 60

Libraries using Span<T> ( just some) ▸ Utf8Json ▸ SpanJson ▸ ZeroFormatter ▸ StackExchange.Redis

Slide 61

Slide 61

Case study JustEat.StatsD PRs Low hanging fruit: #55, #59, #63, #65 Master class by dv00d00: #104 - Zero Allocations

Slide 62

Slide 62

Good Reads Adam Sitnik - Span Marc Gravell - Spans and ref Parts 1 & 2 Span<T> spec Vladimir Sadov All About Span: Exploring a New .NET Mainstay Stephen Toub ▸ Maarten Balliauw ▸ ▸ ▸ ▸ ▸

Slide 63

Slide 63

Summary

Slide 64

Slide 64

THANKS! Any questions? You can find me at @stuartblang