A (brief) overview of Span<T>

A (brief) overview of Span<T>
(and ReadOnlySpan<T> and Memory<T> and ReadOnlyMemory<T>)
DAVID WENGIER
@davidwengier
What is Span<T>?
- Stephen Toub, MSDN Magazine, January 2018
https://msdn.microsoft.com/en-us/magazine/mt814808
“System.Span<T> is a new value type at the heart of .NET [that]
enables the representation of contiguous regions of arbitrary
memory”
What is Span<T>?
• struct
• Part of System.Memory, available on Nuget
• Currently at rc1 version (prerelease)
• .NET Standard 1.0 so can be used in .NET 4.5+
• C# 7.2-ish
“System.Span<T> is a new value type at the heart of .NET [that]
enables the representation of contiguous regions of arbitrary
memory”
What is Span<T>?
• High performance, low (no) overhead
• Framework, CLR, JIT and GC support
• Provides memory and type safety
• Avoids the need for unsafe code
“System.Span<T> is a new value type at the heart of .NET [that]
enables the representation of contiguous regions of arbitrary
memory”
What is Span<T>?
• Native/unmanaged memory (P/Invoke)
• Managed memory (.NET types)
• Stack memory (stackalloc)
“System.Span<T> is a new value type at the heart of .NET [that]
enables the representation of contiguous regions of arbitrary
memory”
What is Span<T>?
• Think of it like having an array to access raw memory
var arr = new byte[10];
Span<byte> bytes = arr;
bytes[0] = 42;
Assert.True(arr[0] == 42);
Span<byte> slice = bytes.Slice(4, 3);
slice[0] = 43;
Assert.True(bytes[4] == 43);
Assert.True(arr[4] == 43);
slice[5] = 44; // IndexOutOfRangeException
HeapStack
0x01
0x02
0x03
0x04
0x05
0x06
string plate = “YGG871”;
plate = plate.Substring(3);
int num = int.Parse(plate);
plate 0x01
“YGG871”
plate 0x02
“871”
num 871
HeapStack
0x01
0x02
0x03
0x04
0x05
0x06
string plate = “YGG871”;
ReadOnlySpan<char> s = plate.AsSpan();
s = s.Slice(3);
int num = int.Parse(s);
plate 0x01
“YGG871”
0x01
0
6
3
num 871
span
offset
pointer
length
.NET Framework 4.5+ - slow span
HeapStack
0x01
0x02
0x03
0x04
0x05
0x06
string plate = “YGG871”;
ReadOnlySpan<char> s = plate.AsSpan();
s = s.Slice(3);
int num = int.Parse(s);
plate 0x01
“YGG871”
0x01+3
3
num 871
ref
span
length
pointer
.NET Core 2.0+ – fast span
* From Adam Sitnik - http://adamsitnik.com/Span/
Method Job Mean StdDev
SpanIndexer_G
et
.NET 4.6 0.6054 ns 0.0007 ns
SpanIndexer_G
et
.NET Core 1.1 0.6047 ns 0.0008 ns
SpanIndexer_G
et
.NET Core 2.0 0.5333 ns 0.0006 ns
SpanIndexer_S
et
.NET 4.6 0.6059 ns 0.0007 ns
SpanIndexer_S
et
.NET Core 1.1 0.6042 ns 0.0002 ns
SpanIndexer_S
et
.NET Core 2.0 0.5205 ns 0.0003 n
Method
String
Length
Mean StdDev Scaled Gen 0
Allocated
*
Substring 10 8.277 ns 0.1938 ns 4.54 0.0191 40 B
Slice 10 1.822 ns 0.0383 ns 1.00 - 0 B
Substring 1000 85.518 ns 1.3474 ns 47.22 0.4919 1032 B
Slice 1000 1.811 ns 0.0205 ns 1.00 - 0 B
* Not including original string
Framework Support
https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/Int32.cs
Framework Support
Framework Support
// RandomStringLoop
var stringChars = new char[Length];
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = (char)(random.Next(0, 10) + '0');
}
return new string(stringChars);
// RandomStringEnumerable
return new string(Enumerable.Repeat("", Length)
.Select(s => (char)(random.Next(0, 10) + '0')).ToArray());
// RandomStringSpan
return string.Create(Length, random, (Span<char> chars, Random r) =>
{
for (int i = 0; i < chars.Length; i++)
{
chars[i] = (char)(r.Next(0, 10) + '0');
}
});
Method Length Mean Scaled Allocated
RandomStringSpan 10 150.29 ns 1.00 48 B
RandomStringLoop 10 156.16 ns 1.04 96 B
RandomStringEnumerable 10 340.26 ns 2.27 192 B
RandomStringSpan 100 1,314.91 ns 1.00 232 B
RandomStringLoop 100 1,361.57 ns 1.04 456 B
RandomStringEnumerable 100 2,140.91 ns 1.63 552 B
RandomStringSpan 1000 12,461.32 ns 1.00 2032 B
RandomStringLoop 1000 14,073.65 ns 1.13 4056 B
RandomStringEnumerable 1000 20,354.63 ns 1.63 4152 B
When do mere mortals use it?
public static bool ContainsCapitalLetters(string s)
{
for (int i = 0; i < s.Length; i++)
{
if (char.IsUpper(s[i]))
{
return true;
}
}
return false;
}
public static int Sum(int[] a)
{
int sum = 0;
for (int i = 0; i < a.Length; i++)
{
sum += a[i];
}
return sum;
}
When do mere mortals use it?
public static bool ContainsCapitalLetters(ReadOnlySpan<char> s)
{
for (int i = 0; i < s.Length; i++)
{
if (char.IsUpper(s[i]))
{
return true;
}
}
return false;
}
public static int Sum(ReadOnlySpan<int> a)
{
int sum = 0;
for (int i = 0; i < a.Length; i++)
{
sum += a[i];
}
return sum;
}
Limitations
• Can only live on the stack
• Implemented as a ref struct
• Can only be contained by ref structs
ref structs
Structs that can exist only on the stack. New in C# 7.2
• Can’t implement interfaces
• Can’t be used as generic type arguments
• Can’t be boxed to object
• Can’t be passed in to - or used in places inside - of async methods,
iterators, nested functions or query expressions
async Task DoSomethingAsync(Span<byte> buffer)
{
buffer[0] = 0;
await Something();
buffer[0] = 1;
}
async Task DoSomethingAsync(Span<byte> buffer)
{
SomethingClass cl = new SomethingClass()
cl.buffer = buffer;
cl.StartSomething();
}
private class SomethingClass
{
public Span<byte> buffer; // illegal
public void Start_Something()
{
buffer[0] = 0;
DoMagicAsyncStuff().ContinueWith(End_Something);
}
public void End_Something()
{
buffer[0] = 1;
}
}
Memory<T>
• “Normal” struct
• Not as performant as Span
• Can be used in more places than Span (ie, doesn’t have the
limitations)
Memory<T>
async Task DoSomethingAsync(Span<byte> buffer)
{
buffer[0] = 0;
await Something(); // Bang!
buffer[0] = 1;
}
async Task DoSomethingAsync(Memory<byte> buffer)
{
buffer.Span[0] = 0;
await Something(); // Totally fine
buffer.Span[0] = 1;
}
Memory<T>
public struct Memory<T>
{
private int _offset;
private int _length;
private int _pointer;
private byte[] _data; // really OwnedMemory<T>
public Span<T> Span => new Span<T>(_data, _pointer, _offset, _length);
}
* Not real
TechEmpower Plaintext
Round 14
Round 15
DAVID WENGIER
@davidwengier
Thank you!
Questions?
1 of 26

Recommended

Adam Sitnik "State of the .NET Performance" by
Adam Sitnik "State of the .NET Performance"Adam Sitnik "State of the .NET Performance"
Adam Sitnik "State of the .NET Performance"Yulia Tsisyk
1.6K views43 slides
ORAM by
ORAMORAM
ORAMAshutosh Satapathy
299 views136 slides
ORAM: A Brief Overview by
ORAM: A Brief OverviewORAM: A Brief Overview
ORAM: A Brief OverviewDev Nath
2.9K views42 slides
Acm aleppo cpc training second session by
Acm aleppo cpc training second sessionAcm aleppo cpc training second session
Acm aleppo cpc training second sessionAhmad Bashar Eter
236 views31 slides
Acm aleppo cpc training ninth session by
Acm aleppo cpc training ninth sessionAcm aleppo cpc training ninth session
Acm aleppo cpc training ninth sessionAhmad Bashar Eter
262 views29 slides
【論文紹介】Relay: A New IR for Machine Learning Frameworks by
【論文紹介】Relay: A New IR for Machine Learning Frameworks【論文紹介】Relay: A New IR for Machine Learning Frameworks
【論文紹介】Relay: A New IR for Machine Learning FrameworksTakeo Imai
2.3K views22 slides

More Related Content

What's hot

Data type by
Data typeData type
Data typemyrajendra
951 views28 slides
Strings by
StringsStrings
StringsMichael Gordon
1.3K views7 slides
Engineering fast indexes (Deepdive) by
Engineering fast indexes (Deepdive)Engineering fast indexes (Deepdive)
Engineering fast indexes (Deepdive)Daniel Lemire
7.4K views37 slides
AA-sort with SSE4.1 by
AA-sort with SSE4.1AA-sort with SSE4.1
AA-sort with SSE4.1MITSUNARI Shigeo
3.4K views29 slides
16 strings-and-text-processing-120712074956-phpapp02 by
16 strings-and-text-processing-120712074956-phpapp0216 strings-and-text-processing-120712074956-phpapp02
16 strings-and-text-processing-120712074956-phpapp02Abdul Samee
199 views73 slides
Patterns of 64-bit errors in games by
Patterns of 64-bit errors in gamesPatterns of 64-bit errors in games
Patterns of 64-bit errors in gamesAndrey Karpov
106 views52 slides

What's hot(20)

Engineering fast indexes (Deepdive) by Daniel Lemire
Engineering fast indexes (Deepdive)Engineering fast indexes (Deepdive)
Engineering fast indexes (Deepdive)
Daniel Lemire7.4K views
16 strings-and-text-processing-120712074956-phpapp02 by Abdul Samee
16 strings-and-text-processing-120712074956-phpapp0216 strings-and-text-processing-120712074956-phpapp02
16 strings-and-text-processing-120712074956-phpapp02
Abdul Samee199 views
Patterns of 64-bit errors in games by Andrey Karpov
Patterns of 64-bit errors in gamesPatterns of 64-bit errors in games
Patterns of 64-bit errors in games
Andrey Karpov106 views
Vc4c development of opencl compiler for videocore4 by nomaddo
Vc4c  development of opencl compiler for videocore4Vc4c  development of opencl compiler for videocore4
Vc4c development of opencl compiler for videocore4
nomaddo5.4K views
Sparse Data Structures for Weighted Bipartite Matching by Jason Riedy
Sparse Data Structures for Weighted Bipartite Matching Sparse Data Structures for Weighted Bipartite Matching
Sparse Data Structures for Weighted Bipartite Matching
Jason Riedy427 views
Strings Functions in C Programming by DevoAjit Gupta
Strings Functions in C ProgrammingStrings Functions in C Programming
Strings Functions in C Programming
DevoAjit Gupta3.2K views
A nice 64-bit error in C by PVS-Studio
A  nice 64-bit error in CA  nice 64-bit error in C
A nice 64-bit error in C
PVS-Studio33 views
C++ Code as Seen by a Hypercritical Reviewer by Andrey Karpov
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
Andrey Karpov143 views
String in c programming by Devan Thakur
String in c programmingString in c programming
String in c programming
Devan Thakur6K views
Strings in c by vampugani
Strings in cStrings in c
Strings in c
vampugani2.4K views
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and... by MITSUNARI Shigeo
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...
MITSUNARI Shigeo3.1K views
Arrays in C++ in Tamil - TNSCERT SYLLABUS PPT by LATHA LAKSHMI
Arrays in C++ in Tamil - TNSCERT SYLLABUS PPT Arrays in C++ in Tamil - TNSCERT SYLLABUS PPT
Arrays in C++ in Tamil - TNSCERT SYLLABUS PPT
LATHA LAKSHMI615 views

Similar to A (brief) overview of Span<T>

State of the .Net Performance by
State of the .Net PerformanceState of the .Net Performance
State of the .Net PerformanceCUSTIS
198 views43 slides
Tamir Dresher - DotNet 7 What's new.pptx by
Tamir Dresher - DotNet 7 What's new.pptxTamir Dresher - DotNet 7 What's new.pptx
Tamir Dresher - DotNet 7 What's new.pptxTamir Dresher
27 views40 slides
primitive data types by
 primitive data types primitive data types
primitive data typesJadavsejal
96 views17 slides
C# 7.x What's new and what's coming with C# 8 by
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8Christian Nagel
266 views56 slides
Getting started cpp full by
Getting started cpp   fullGetting started cpp   full
Getting started cpp fullVõ Hòa
491 views245 slides
Egor Bogatov - .NET Core intrinsics and other micro-optimizations by
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov
3.6K views53 slides

Similar to A (brief) overview of Span<T>(20)

State of the .Net Performance by CUSTIS
State of the .Net PerformanceState of the .Net Performance
State of the .Net Performance
CUSTIS198 views
Tamir Dresher - DotNet 7 What's new.pptx by Tamir Dresher
Tamir Dresher - DotNet 7 What's new.pptxTamir Dresher - DotNet 7 What's new.pptx
Tamir Dresher - DotNet 7 What's new.pptx
Tamir Dresher27 views
primitive data types by Jadavsejal
 primitive data types primitive data types
primitive data types
Jadavsejal96 views
C# 7.x What's new and what's coming with C# 8 by Christian Nagel
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8
Christian Nagel266 views
Getting started cpp full by Võ Hòa
Getting started cpp   fullGetting started cpp   full
Getting started cpp full
Võ Hòa491 views
Egor Bogatov - .NET Core intrinsics and other micro-optimizations by Egor Bogatov
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov3.6K views
C++ process new by 敬倫 林
C++ process newC++ process new
C++ process new
敬倫 林3.4K views
Tools and Techniques for Understanding Threading Behavior in Android by Intel® Software
Tools and Techniques for Understanding Threading Behavior in AndroidTools and Techniques for Understanding Threading Behavior in Android
Tools and Techniques for Understanding Threading Behavior in Android
Intel® Software585 views
The Ring programming language version 1.9 book - Part 100 of 210 by Mahmoud Samir Fayed
The Ring programming language version 1.9 book - Part 100 of 210The Ring programming language version 1.9 book - Part 100 of 210
The Ring programming language version 1.9 book - Part 100 of 210
Deep dumpster diving 2010 by RonnBlack
Deep dumpster diving 2010Deep dumpster diving 2010
Deep dumpster diving 2010
RonnBlack423 views
Georgy Nosenko - An introduction to the use SMT solvers for software security by DefconRussia
Georgy Nosenko - An introduction to the use SMT solvers for software securityGeorgy Nosenko - An introduction to the use SMT solvers for software security
Georgy Nosenko - An introduction to the use SMT solvers for software security
DefconRussia3.3K views
C Programming Training in Ambala ! Batra Computer Centre by jatin batra
C Programming Training in Ambala ! Batra Computer CentreC Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer Centre
jatin batra67 views
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321 by Teddy Hsiung
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
Teddy Hsiung140 views
OpenStack Congress and Datalog (English) by Motonori Shindo
OpenStack Congress and Datalog (English)OpenStack Congress and Datalog (English)
OpenStack Congress and Datalog (English)
Motonori Shindo3.3K views
Where the wild things are - Benchmarking and Micro-Optimisations by Matt Warren
Where the wild things are - Benchmarking and Micro-OptimisationsWhere the wild things are - Benchmarking and Micro-Optimisations
Where the wild things are - Benchmarking and Micro-Optimisations
Matt Warren1.5K views

More from David Wengier

A (very) opinionated guide to MSBuild and Project Files by
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project FilesDavid Wengier
126 views22 slides
Lowering in C#: What really happens with your code?, from NDC Oslo 2019 by
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019David Wengier
373 views39 slides
Pragmatic Performance from NDC Oslo 2019 by
Pragmatic Performance from NDC Oslo 2019Pragmatic Performance from NDC Oslo 2019
Pragmatic Performance from NDC Oslo 2019David Wengier
354 views32 slides
Pragmatic Performance from NDC London 2019 by
Pragmatic Performance from NDC London 2019Pragmatic Performance from NDC London 2019
Pragmatic Performance from NDC London 2019David Wengier
908 views32 slides
Introduction to Amazon Echo Skills by
Introduction to Amazon Echo SkillsIntroduction to Amazon Echo Skills
Introduction to Amazon Echo SkillsDavid Wengier
188 views7 slides
Performance and Benchmarking by
Performance and BenchmarkingPerformance and Benchmarking
Performance and BenchmarkingDavid Wengier
238 views28 slides

More from David Wengier(6)

A (very) opinionated guide to MSBuild and Project Files by David Wengier
A (very) opinionated guide to MSBuild and Project FilesA (very) opinionated guide to MSBuild and Project Files
A (very) opinionated guide to MSBuild and Project Files
David Wengier126 views
Lowering in C#: What really happens with your code?, from NDC Oslo 2019 by David Wengier
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
David Wengier373 views
Pragmatic Performance from NDC Oslo 2019 by David Wengier
Pragmatic Performance from NDC Oslo 2019Pragmatic Performance from NDC Oslo 2019
Pragmatic Performance from NDC Oslo 2019
David Wengier354 views
Pragmatic Performance from NDC London 2019 by David Wengier
Pragmatic Performance from NDC London 2019Pragmatic Performance from NDC London 2019
Pragmatic Performance from NDC London 2019
David Wengier908 views
Introduction to Amazon Echo Skills by David Wengier
Introduction to Amazon Echo SkillsIntroduction to Amazon Echo Skills
Introduction to Amazon Echo Skills
David Wengier188 views
Performance and Benchmarking by David Wengier
Performance and BenchmarkingPerformance and Benchmarking
Performance and Benchmarking
David Wengier238 views

Recently uploaded

PRODUCT LISTING.pptx by
PRODUCT LISTING.pptxPRODUCT LISTING.pptx
PRODUCT LISTING.pptxangelicacueva6
18 views1 slide
"Node.js Development in 2024: trends and tools", Nikita Galkin by
"Node.js Development in 2024: trends and tools", Nikita Galkin "Node.js Development in 2024: trends and tools", Nikita Galkin
"Node.js Development in 2024: trends and tools", Nikita Galkin Fwdays
17 views38 slides
PharoJS - Zürich Smalltalk Group Meetup November 2023 by
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023Noury Bouraqadi
139 views17 slides
Igniting Next Level Productivity with AI-Infused Data Integration Workflows by
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Safe Software
317 views86 slides
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf by
STKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdfSTKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdf
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdfDr. Jimmy Schwarzkopf
24 views29 slides
"Surviving highload with Node.js", Andrii Shumada by
"Surviving highload with Node.js", Andrii Shumada "Surviving highload with Node.js", Andrii Shumada
"Surviving highload with Node.js", Andrii Shumada Fwdays
33 views29 slides

Recently uploaded(20)

"Node.js Development in 2024: trends and tools", Nikita Galkin by Fwdays
"Node.js Development in 2024: trends and tools", Nikita Galkin "Node.js Development in 2024: trends and tools", Nikita Galkin
"Node.js Development in 2024: trends and tools", Nikita Galkin
Fwdays17 views
PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi139 views
Igniting Next Level Productivity with AI-Infused Data Integration Workflows by Safe Software
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Safe Software317 views
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf by Dr. Jimmy Schwarzkopf
STKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdfSTKI Israeli Market Study 2023   corrected forecast 2023_24 v3.pdf
STKI Israeli Market Study 2023 corrected forecast 2023_24 v3.pdf
"Surviving highload with Node.js", Andrii Shumada by Fwdays
"Surviving highload with Node.js", Andrii Shumada "Surviving highload with Node.js", Andrii Shumada
"Surviving highload with Node.js", Andrii Shumada
Fwdays33 views
SAP Automation Using Bar Code and FIORI.pdf by Virendra Rai, PMP
SAP Automation Using Bar Code and FIORI.pdfSAP Automation Using Bar Code and FIORI.pdf
SAP Automation Using Bar Code and FIORI.pdf
Future of AR - Facebook Presentation by ssuserb54b561
Future of AR - Facebook PresentationFuture of AR - Facebook Presentation
Future of AR - Facebook Presentation
ssuserb54b56122 views
Five Things You SHOULD Know About Postman by Postman
Five Things You SHOULD Know About PostmanFive Things You SHOULD Know About Postman
Five Things You SHOULD Know About Postman
Postman38 views
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe by Simone Puorto
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe
2024: A Travel Odyssey The Role of Generative AI in the Tourism Universe
Simone Puorto13 views
STPI OctaNE CoE Brochure.pdf by madhurjyapb
STPI OctaNE CoE Brochure.pdfSTPI OctaNE CoE Brochure.pdf
STPI OctaNE CoE Brochure.pdf
madhurjyapb14 views
Case Study Copenhagen Energy and Business Central.pdf by Aitana
Case Study Copenhagen Energy and Business Central.pdfCase Study Copenhagen Energy and Business Central.pdf
Case Study Copenhagen Energy and Business Central.pdf
Aitana17 views
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas... by Bernd Ruecker
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
Bernd Ruecker48 views
Business Analyst Series 2023 - Week 3 Session 5 by DianaGray10
Business Analyst Series 2023 -  Week 3 Session 5Business Analyst Series 2023 -  Week 3 Session 5
Business Analyst Series 2023 - Week 3 Session 5
DianaGray10345 views
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ... by Jasper Oosterveld
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...

A (brief) overview of Span<T>

  • 1. A (brief) overview of Span<T> (and ReadOnlySpan<T> and Memory<T> and ReadOnlyMemory<T>) DAVID WENGIER @davidwengier
  • 2. What is Span<T>? - Stephen Toub, MSDN Magazine, January 2018 https://msdn.microsoft.com/en-us/magazine/mt814808 “System.Span<T> is a new value type at the heart of .NET [that] enables the representation of contiguous regions of arbitrary memory”
  • 3. What is Span<T>? • struct • Part of System.Memory, available on Nuget • Currently at rc1 version (prerelease) • .NET Standard 1.0 so can be used in .NET 4.5+ • C# 7.2-ish “System.Span<T> is a new value type at the heart of .NET [that] enables the representation of contiguous regions of arbitrary memory”
  • 4. What is Span<T>? • High performance, low (no) overhead • Framework, CLR, JIT and GC support • Provides memory and type safety • Avoids the need for unsafe code “System.Span<T> is a new value type at the heart of .NET [that] enables the representation of contiguous regions of arbitrary memory”
  • 5. What is Span<T>? • Native/unmanaged memory (P/Invoke) • Managed memory (.NET types) • Stack memory (stackalloc) “System.Span<T> is a new value type at the heart of .NET [that] enables the representation of contiguous regions of arbitrary memory”
  • 6. What is Span<T>? • Think of it like having an array to access raw memory
  • 7. var arr = new byte[10]; Span<byte> bytes = arr; bytes[0] = 42; Assert.True(arr[0] == 42); Span<byte> slice = bytes.Slice(4, 3); slice[0] = 43; Assert.True(bytes[4] == 43); Assert.True(arr[4] == 43); slice[5] = 44; // IndexOutOfRangeException
  • 8. HeapStack 0x01 0x02 0x03 0x04 0x05 0x06 string plate = “YGG871”; plate = plate.Substring(3); int num = int.Parse(plate); plate 0x01 “YGG871” plate 0x02 “871” num 871
  • 9. HeapStack 0x01 0x02 0x03 0x04 0x05 0x06 string plate = “YGG871”; ReadOnlySpan<char> s = plate.AsSpan(); s = s.Slice(3); int num = int.Parse(s); plate 0x01 “YGG871” 0x01 0 6 3 num 871 span offset pointer length .NET Framework 4.5+ - slow span
  • 10. HeapStack 0x01 0x02 0x03 0x04 0x05 0x06 string plate = “YGG871”; ReadOnlySpan<char> s = plate.AsSpan(); s = s.Slice(3); int num = int.Parse(s); plate 0x01 “YGG871” 0x01+3 3 num 871 ref span length pointer .NET Core 2.0+ – fast span
  • 11. * From Adam Sitnik - http://adamsitnik.com/Span/ Method Job Mean StdDev SpanIndexer_G et .NET 4.6 0.6054 ns 0.0007 ns SpanIndexer_G et .NET Core 1.1 0.6047 ns 0.0008 ns SpanIndexer_G et .NET Core 2.0 0.5333 ns 0.0006 ns SpanIndexer_S et .NET 4.6 0.6059 ns 0.0007 ns SpanIndexer_S et .NET Core 1.1 0.6042 ns 0.0002 ns SpanIndexer_S et .NET Core 2.0 0.5205 ns 0.0003 n
  • 12. Method String Length Mean StdDev Scaled Gen 0 Allocated * Substring 10 8.277 ns 0.1938 ns 4.54 0.0191 40 B Slice 10 1.822 ns 0.0383 ns 1.00 - 0 B Substring 1000 85.518 ns 1.3474 ns 47.22 0.4919 1032 B Slice 1000 1.811 ns 0.0205 ns 1.00 - 0 B * Not including original string
  • 15. Framework Support // RandomStringLoop var stringChars = new char[Length]; for (int i = 0; i < stringChars.Length; i++) { stringChars[i] = (char)(random.Next(0, 10) + '0'); } return new string(stringChars); // RandomStringEnumerable return new string(Enumerable.Repeat("", Length) .Select(s => (char)(random.Next(0, 10) + '0')).ToArray()); // RandomStringSpan return string.Create(Length, random, (Span<char> chars, Random r) => { for (int i = 0; i < chars.Length; i++) { chars[i] = (char)(r.Next(0, 10) + '0'); } });
  • 16. Method Length Mean Scaled Allocated RandomStringSpan 10 150.29 ns 1.00 48 B RandomStringLoop 10 156.16 ns 1.04 96 B RandomStringEnumerable 10 340.26 ns 2.27 192 B RandomStringSpan 100 1,314.91 ns 1.00 232 B RandomStringLoop 100 1,361.57 ns 1.04 456 B RandomStringEnumerable 100 2,140.91 ns 1.63 552 B RandomStringSpan 1000 12,461.32 ns 1.00 2032 B RandomStringLoop 1000 14,073.65 ns 1.13 4056 B RandomStringEnumerable 1000 20,354.63 ns 1.63 4152 B
  • 17. When do mere mortals use it? public static bool ContainsCapitalLetters(string s) { for (int i = 0; i < s.Length; i++) { if (char.IsUpper(s[i])) { return true; } } return false; } public static int Sum(int[] a) { int sum = 0; for (int i = 0; i < a.Length; i++) { sum += a[i]; } return sum; }
  • 18. When do mere mortals use it? public static bool ContainsCapitalLetters(ReadOnlySpan<char> s) { for (int i = 0; i < s.Length; i++) { if (char.IsUpper(s[i])) { return true; } } return false; } public static int Sum(ReadOnlySpan<int> a) { int sum = 0; for (int i = 0; i < a.Length; i++) { sum += a[i]; } return sum; }
  • 19. Limitations • Can only live on the stack • Implemented as a ref struct • Can only be contained by ref structs
  • 20. ref structs Structs that can exist only on the stack. New in C# 7.2 • Can’t implement interfaces • Can’t be used as generic type arguments • Can’t be boxed to object • Can’t be passed in to - or used in places inside - of async methods, iterators, nested functions or query expressions
  • 21. async Task DoSomethingAsync(Span<byte> buffer) { buffer[0] = 0; await Something(); buffer[0] = 1; } async Task DoSomethingAsync(Span<byte> buffer) { SomethingClass cl = new SomethingClass() cl.buffer = buffer; cl.StartSomething(); } private class SomethingClass { public Span<byte> buffer; // illegal public void Start_Something() { buffer[0] = 0; DoMagicAsyncStuff().ContinueWith(End_Something); } public void End_Something() { buffer[0] = 1; } }
  • 22. Memory<T> • “Normal” struct • Not as performant as Span • Can be used in more places than Span (ie, doesn’t have the limitations)
  • 23. Memory<T> async Task DoSomethingAsync(Span<byte> buffer) { buffer[0] = 0; await Something(); // Bang! buffer[0] = 1; } async Task DoSomethingAsync(Memory<byte> buffer) { buffer.Span[0] = 0; await Something(); // Totally fine buffer.Span[0] = 1; }
  • 24. Memory<T> public struct Memory<T> { private int _offset; private int _length; private int _pointer; private byte[] _data; // really OwnedMemory<T> public Span<T> Span => new Span<T>(_data, _pointer, _offset, _length); } * Not real