SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Íèçêîóðîâíåâûå îïòèìèçàöèè .NET-ïðèëîæåíèé 
Àíäðåé Àêèíüøèí 
Áàðíàóëüñêîå ñîîáùåñòâî .NET ðàçðàáîò÷èêîâ 
bug.ineta.ru 
www.facebook.com/groups/dotnetbarnaul/
Îïòèìèçèðîâàòü èëè íå 
îïòèìèçèðîâàòü? 
Premature optimization is the root of all evil. 

c Donald Ervin Knuth
Ïðàâèëüíûé ïîäõîä 
 Õîðîøèå àëãîðèòìû 
 Õîðîøèå ñòðóêòóðû äàííûõ 
 Ìàëîå êîëè÷åñòâî òÿæ¼ëûõ îïåðàöèé
Îïòèìèçàöèè
Memory traffic 
 Memory traffic  ýòî ïëîõî. 
 Ìíîãî îáúåêòîâ ! GC òÿæåëî. 
 Ðàçíàÿ öåíà îáúåêòîâ â Gen0, Gen1, Gen2, LOH. 
 Ëèøíèé memory traffic: LINQ, óïàêîâêà, áîëüøèå 
îáúåêòû, îòñóòñòâèå èíòåðíèðîâàíèÿ è ïóëîâ 
îáúåêòîâ è ìíîãîå äðóãîå.
Memory traffic: çàìûêàíèÿ 
void Foo(Funcint, int inc) { } 
void Run() 
{ 
int y = 1; 
Foo(x = x + y); 
}
Memory traffic: çàìûêàíèÿ 
private void Foo(Funcint, int inc) 
{} 
private void Run() 
{ 
Program.c__DisplayClass1 cDisplayClass1 = new Program.c__DisplayClass1(); 
cDisplayClass1.y = 1; 
this.Foo(new Funcint, int((object) cDisplayClass1, __methodptr(b__0))); 
} 
[CompilerGenerated] 
private sealed class c__DisplayClass1 
{ 
public int y; 
public c__DisplayClass1() 
{ 
base..ctor(); 
} 
public int Runb__0(int x) 
{ 
return x + this.y; 
} 
}
Memory traffic: çàìûêàíèÿ 
void Foo(Funcobject before, 
Funcobject after) 
{ 
before(); 
// Some logic 
after(); 
} 
void Run() 
{ 
var a = new object(); 
var b = new object(); 
Foo(() = a, () = b); 
}
Memory traffic: çàìûêàíèÿ 
private void Run() 
{ 
Program.c__DisplayClass2 cDisplayClass2 = new Program.c__DisplayClass2(); 
cDisplayClass2.a = new object(); 
cDisplayClass2.b = new object(); 
this.Foo(new Funcobject((object) cDisplayClass2, __methodptr(Runb__0)), 
new Funcobject((object) cDisplayClass2, __methodptr(Runb__1))); 
} 
[CompilerGenerated] 
private sealed class c__DisplayClass2 
{ 
public object a; 
public object b; 
public c__DisplayClass2() 
{ 
base..ctor(); 
} 
public object Runb__0() 
{ 
return this.a; 
} 
public object Runb__1() 
{ 
return this.b; 
} 
}
Memory traffic: çàìûêàíèÿ 
void Foo(Funcint, int inc) { } 
static int y = 1; 
static int StaticInc(int x) { return x + y; } 
void Run() 
{ 
Foo(x = StaticInc(x)); 
Foo(StaticInc); 
}
Memory traffic: çàìûêàíèÿ 
private void Run() 
{ 
if (Program.CS$9__CachedAnonymousMethodDelegate1 == null) 
{ 
Program.CS$9__CachedAnonymousMethodDelegate1 = 
new Funcint, int((object) null, __methodptr(Runb__0)); 
} 
this.Foo(Program.CS$9__CachedAnonymousMethodDelegate1); 
this.Foo(new Funcint, int((object) null, __methodptr(StaticInc))); 
} 
[CompilerGenerated] 
private static int Runb__0(int x) 
{ 
return Program.StaticInc(x); 
} 
[CompilerGenerated] 
private static Funcint, int CS$9__CachedAnonymousMethodDelegate1;
Memory traffic: params 
void Foo(params int[] x) { } 
void Main() 
{ 
Foo(); 
// IL_0001: ldarg.0 
// IL_0002: ldc.i4.0 
// IL_0003: newarr 
// IL_0008: call 
}
Memory traffic: yeild 
IEnumerableint Foo() 
{ 
for (int i = 0; i  5; i++) 
yield return i; 
}
Memory traffic: yield 
private IEnumerableint Foo() 
{ 
Program.Food__0 fooD0 = new Program.Food__0(-2); 
fooD0.4__this = this; 
return (IEnumerableint) fooD0; 
} 
[CompilerGenerated] 
private sealed class Food__0 : IEnumerableint, IEnumerable, 
CIEnumeratorint, IEnumerator, IDisposable 
{ 
private int 2__current; 
private int 1__state; 
private int l__initialThreadId; 
public int i5__1; 
public Program 4__this; 
...
Memory traffic: List vs IList 
void Foo1(Listint list) 
{ 
var start = GC.GetTotalMemory(true); 
foreach (var i in list) 
Console.WriteLine(GC.GetTotalMemory(true) - start); 
} 
void Foo2(IListint list) 
{ 
var start = GC.GetTotalMemory(true); 
foreach (var i in list) 
Console.WriteLine(GC.GetTotalMemory(true) - start); 
} 
void Run() 
{ 
var list = new Listint { 1 }; 
Foo1(list); 
Foo2(list); 
}
Memory traffic: ìàëåíüêèé List 
struct SmallListT : IListT 
{ 
private T item1; 
private T item2; 
private T item3; 
private ListT otherItems; 
public ListT ToList() { ... } 
}
Ìèêðîáåí÷ìàðêè 
Òðåáîâàíèÿ: 
 Ïîëó÷åíèå ìåòðèê 
 Âîñïðîèçâîäèìîñòü 
 Îáúåêòèâíîñòü 
 Îòñóòñòâèå ñàéä-ýôôåêòîâ
Êàê çàïóñêàòü áåí÷ìàðê? 
 Release mode 
 Without debugging 
 Ïðîãðåâ 
 Çàïóñê íà îäíîì ÿäðå 
 ×èñòîå îêðóæåíèå 
 Ìíîãîêðàòíûé çàïóñê â ðàçíûõ îêðóæåíèÿõ
Íóæíî ïîìíèòü ïðî: 
 Dead code elmintation 
 Inlining 
 Folding 
 Branch prediction 
 600+ äðóãèõ îïòèìèçàöèé
Interface implementation 
interface IFoo 
{ 
int Inc(int x); 
} 
class FastFoo : IFoo 
{ 
public int Inc(int x) 
{ 
return x + 1; 
} 
} 
class SlowFoo : IFoo 
{ 
public int Inc(int x) 
{ 
return 1 + x; 
} 
} 
void DoIt(IFoo foo) 
{ 
for (int i = 0; i  1000000000; i++) 
foo.Inc(0); 
} 
DoIt(new FastFoo()); 
DoIt(new SlowFoo());
Readonly fields 
public struct Int256 
{ 
private readonly long bits0, bits1, bits2, bits3; 
public Int256(long bits0, long bits1, long bits2, long bits3) 
{ 
this.bits0 = bits0; this.bits1 = bits1; this.bits2 = bits2; this.bits3 = bits3; 
} 
public long Bits0 { get { return bits0; } } 
public long Bits1 { get { return bits1; } } 
public long Bits2 { get { return bits2; } } 
public long Bits3 { get { return bits3; } } 
} 
class Test 
{ 
private readonly Int256 value; // private Int256 value; 
public Test() { value = new Int256(1L, 5L, 10L, 100L); } 
public long TotalValue { get { return value.Bits0 + value.Bits1 + value.Bits2 + value.Bits3; } } 
public void RunTest() 
{ 
var sample = TotalValue; 
Stopwatch sw = Stopwatch.StartNew(); 
long total = 0; 
for (int i = 0; i  1000000000; i++) total += TotalValue; 
sw.Stop(); 
Console.WriteLine(Total time: {0}ms, sw.ElapsedMilliseconds); 
} 
static void Main() { new Test().RunTest(); } 
} 

c Jon Skeet, Micro-optimization: the surprising inefficiency of readonly fields
Îñòîðîæíåå ñ ÎÎÏ! 
Êðàñèâûé äèçàéí íå âñåãäà ñî÷åòàåòñÿ ñ âûñîêîé 
ïðîèçâîäèòåëüíîñòüþ.
Reflection 
static MemoryLeakFixer() 
{ 
var fields = typeof(DisposableObject).GetFields( 
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
fieldInfo = fields.FirstOrDefault(f = f.FieldType == typeof(GCHandle)); 
} 
public static void FixAfterRelease(DisposableObject obj) 
{ 
if (obj.IsDisposed) 
{ 
var dataHandle = (GCHandle)fieldInfo.GetValue(obj); 
if (dataHandle.IsAllocated) 
dataHandle.Free(); 
} 
}
StructLayout 
[StructLayout(LayoutKind.Explicit)] 
struct MyStruct 
{ 
[FieldOffset(0)] 
public Int16 Value; 
[FieldOffset(0)] 
public Byte LowByte; 
} 
var s = new MyStruct(); 
s.Value = 256 + 100; 
Console.WriteLine(s.LowByte); // 100
×¼ðíàÿ ìàãèÿ 
public class MyObject 
{ 
public long X; 
} 
public class Pumpkin 
{ 
public int Y1; 
public int Y2; 
} 
public unsafe IntPtr GetAddress(object obj) 
{ 
var typedReference = __makeref(obj); 
return *(IntPtr*)(typedReference); 
} 
public unsafe T ConvertT(IntPtr address) 
{ 
var fakeInstance = default(T); 
var typedReference = __makeref(fakeInstance); 
*(IntPtr*)(typedReference) = address; 
return __refvalue( typedReference,T); 
} 
public void Run() 
{ 
var myObject = new MyObject { X = 1 + (2L  32) }; 
var pumpkin = ConvertPumpkin(GetAddress(myObject)); 
Console.WriteLine(pumpkin.Y1 +   + pumpkin.Y2); // 1 2 
myObject.X = 3 + (4L  32); 
Console.WriteLine(pumpkin.Y1 +   + pumpkin.Y2); // 3 4 
}
Íóæíî ïîíèìàòü 
// sscli20clrsrcvmtypehandle.h 
// A TypeHandle is the FUNDAMENTAL concept of type identity in the CLR. 
// That is two types are equal if and only if their type handles 
// are equal. A TypeHandle, is a pointer sized struture that encodes 
// everything you need to know to figure out what kind of type you are 
// actually dealing with. 
// At the present time a TypeHandle can point at two possible things 
// 
// 1) A MethodTable (Intrinsics, Classes, Value Types and their instantiations) 
// 2) A TypeDesc (all other cases: arrays, byrefs, pointer types, 
// function pointers, generic type variables) 
// 
// or with IL stubs, a third thing: 
// 
// 3) A MethodTable for a native value type.
Íóæíî ïîíèìàòü 
private void Print(Type type) 
{ 
bool isTypeDesc = ((int)type.TypeHandle.Value  2)  0; 
Console.WriteLine({0}: {1} = {2}, 
type.Name.PadRight(10), 
type.TypeHandle.Value.ToString(X), 
(isTypeDesc ? TypeDesc : MethodTable)); 
} 
private void Run() 
{ 
Print(typeof(int)); 
Print(typeof(object)); 
Print(typeof(Stream)); 
Print(typeof(int[])); 
Print(typeof(int[][])); 
Print(typeof(object[])); 
} 
// Int32 : 65C4C480 = MethodTable 
// Object : 65C4B060 = MethodTable 
// Stream : 65C4D954 = MethodTable 
// Int32[] : 65854C8A = TypeDesc 
// Int32[][] : 658F6BD6 = TypeDesc 
// Object[] : 65854D7A = TypeDesc
Öèêëû 
public int Foo997() 
{ 
int sum = 0; 
for (int i = 0; i  997; i++) 
sum += a[i]; 
return sum; 
} 
public int Foo1000() 
{ 
int sum = 0; 
for (int i = 0; i  1000; i++) 
sum += a[i]; 
return sum; 
}
Öèêëû
Ïàðàëëåëèçì èíñòðóêöèé 
int iterationCount = 256 * 1024 * 1024; 
int[] a = new int[2]; 
for (int i = 0; i  iterationCount; i++) 
{ 
a[0]++; 
a[0]++; 
} 
for (int i = 0; i  iterationCount; i++) 
{ 
a[0]++; 
a[1]++; 
}
Êýø ïðîöåññîðà 
int[] x = new int[64 * 1024 * 1024]; 
for (int i = 0; i  x.Length; i++) 
x[i] *= 3; 
for (int i = 0; i  x.Length; i += 16) 
x[i] *= 3;
Êýø ïðîöåññîðà 
Óìíîæåíèå ìàòðèö: 
// Standard 
for (k = 0; k  n; k++) 
for (i = 0; i  n; i++) 
for (j = 0; j  n; j++) 
c[k][i] = c[k][i] + a[k][j]*b[j][i]; 
// Optimized 
for (k = 0; k  n; k++) 
for (i = 0; i  n; i++) 
for (j = 0; j  n; j++) 
c[i][j] = c[i][j] + a[i][k]*b[k][j];
Êýø ïðîöåññîðà
Êýø ïðîöåññîðà 
Binary Search
Êýø ïðîöåññîðà 
Cache-Conscious Binary Search
Êýø ïðîöåññîðà 
False sharing 
private const int Step = 1; 
private static int[] x = new int[1024]; 
private void Foo(int p) 
{ 
for (int j = 0; j  1000000000; j++) 
x[p] = x[p] + 3; 
} 
private void Run() 
{ 
var s = Stopwatch.StartNew(); 
var tasks = new Task[4]; 
tasks[0] = Task.Factory.StartNew(() = Foo(0 * Step)); 
tasks[1] = Task.Factory.StartNew(() = Foo(1 * Step)); 
tasks[2] = Task.Factory.StartNew(() = Foo(2 * Step)); 
tasks[3] = Task.Factory.StartNew(() = Foo(3 * Step)); 
Task.WaitAll(tasks); 
Console.WriteLine(s.ElapsedMilliseconds); 
} 
À òåïåðü ïîäóìàéòå ïðî CardTable...
Íàïóòñòâèå 
Îïòèìèçèðóéòå îñòîðîæíî!

Contenu connexe

Tendances

Why learn new programming languages
Why learn new programming languagesWhy learn new programming languages
Why learn new programming languagesJonas Follesø
 
C Code and the Art of Obfuscation
C Code and the Art of ObfuscationC Code and the Art of Obfuscation
C Code and the Art of Obfuscationguest9006ab
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcescorehard_by
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Datagreenwop
 
Flashback, el primer malware masivo de sistemas Mac
Flashback, el primer malware masivo de sistemas MacFlashback, el primer malware masivo de sistemas Mac
Flashback, el primer malware masivo de sistemas MacESET Latinoamérica
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsAlexander Granin
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Alexander Granin
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляSergey Platonov
 
Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++vidyamittal
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
Advance C++notes
Advance C++notesAdvance C++notes
Advance C++notesRajiv Gupta
 

Tendances (19)

Property-based testing
Property-based testingProperty-based testing
Property-based testing
 
Pre zen ta sion
Pre zen ta sionPre zen ta sion
Pre zen ta sion
 
Why learn new programming languages
Why learn new programming languagesWhy learn new programming languages
Why learn new programming languages
 
C Code and the Art of Obfuscation
C Code and the Art of ObfuscationC Code and the Art of Obfuscation
C Code and the Art of Obfuscation
 
OpenXR 1.0 Reference Guide
OpenXR 1.0 Reference GuideOpenXR 1.0 Reference Guide
OpenXR 1.0 Reference Guide
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
Flashback, el primer malware masivo de sistemas Mac
Flashback, el primer malware masivo de sistemas MacFlashback, el primer malware masivo de sistemas Mac
Flashback, el primer malware masivo de sistemas Mac
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
Python GC
Python GCPython GC
Python GC
 
Python speleology
Python speleologyPython speleology
Python speleology
 
662305 11
662305 11662305 11
662305 11
 
Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++
 
OpenGL 4.4 Reference Card
OpenGL 4.4 Reference CardOpenGL 4.4 Reference Card
OpenGL 4.4 Reference Card
 
OOP v3
OOP v3OOP v3
OOP v3
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Advance C++notes
Advance C++notesAdvance C++notes
Advance C++notes
 

Similaire à Низкоуровневые оптимизации .NET-приложений

Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CSteffen Wenz
 
02. Data Types and variables
02. Data Types and variables02. Data Types and variables
02. Data Types and variablesIntro C# Book
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 
Deep dumpster diving 2010
Deep dumpster diving 2010Deep dumpster diving 2010
Deep dumpster diving 2010RonnBlack
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFTimur Safin
 
public class TrequeT extends AbstractListT { .pdf
  public class TrequeT extends AbstractListT {  .pdf  public class TrequeT extends AbstractListT {  .pdf
public class TrequeT extends AbstractListT { .pdfinfo30292
 
Getting started cpp full
Getting started cpp   fullGetting started cpp   full
Getting started cpp fullVõ Hòa
 
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...Patrick Niedzielski
 
Lec 1 Ds
Lec 1 DsLec 1 Ds
Lec 1 DsQundeel
 
Data Structure
Data StructureData Structure
Data Structuresheraz1
 
Lec 1 Ds
Lec 1 DsLec 1 Ds
Lec 1 DsQundeel
 
Let’s talk about microbenchmarking
Let’s talk about microbenchmarkingLet’s talk about microbenchmarking
Let’s talk about microbenchmarkingAndrey Akinshin
 
A miało być tak... bez wycieków
A miało być tak... bez wyciekówA miało być tak... bez wycieków
A miało być tak... bez wyciekówKonrad Kokosa
 

Similaire à Низкоуровневые оптимизации .NET-приложений (20)

Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
02. Data Types and variables
02. Data Types and variables02. Data Types and variables
02. Data Types and variables
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Deep dumpster diving 2010
Deep dumpster diving 2010Deep dumpster diving 2010
Deep dumpster diving 2010
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
 
Ac2
Ac2Ac2
Ac2
 
Nested loops
Nested loopsNested loops
Nested loops
 
public class TrequeT extends AbstractListT { .pdf
  public class TrequeT extends AbstractListT {  .pdf  public class TrequeT extends AbstractListT {  .pdf
public class TrequeT extends AbstractListT { .pdf
 
C# labprograms
C# labprogramsC# labprograms
C# labprograms
 
Lập trình C
Lập trình CLập trình C
Lập trình C
 
Getting started cpp full
Getting started cpp   fullGetting started cpp   full
Getting started cpp full
 
The zen of async: Best practices for best performance
The zen of async: Best practices for best performanceThe zen of async: Best practices for best performance
The zen of async: Best practices for best performance
 
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...
From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Mo...
 
Minicurso Android
Minicurso AndroidMinicurso Android
Minicurso Android
 
Lec 1 Ds
Lec 1 DsLec 1 Ds
Lec 1 Ds
 
Data Structure
Data StructureData Structure
Data Structure
 
Lec 1 Ds
Lec 1 DsLec 1 Ds
Lec 1 Ds
 
Let’s talk about microbenchmarking
Let’s talk about microbenchmarkingLet’s talk about microbenchmarking
Let’s talk about microbenchmarking
 
Thread
ThreadThread
Thread
 
A miało być tak... bez wycieków
A miało być tak... bez wyciekówA miało być tak... bez wycieków
A miało być tak... bez wycieków
 

Plus de Andrey Akinshin

Поговорим про performance-тестирование
Поговорим про performance-тестированиеПоговорим про performance-тестирование
Поговорим про performance-тестированиеAndrey Akinshin
 
Сложности performance-тестирования
Сложности performance-тестированияСложности performance-тестирования
Сложности performance-тестированияAndrey Akinshin
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркингаAndrey Akinshin
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про памятьAndrey Akinshin
 
Кроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLRКроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLRAndrey Akinshin
 
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
 Теория и практика .NET-бенчмаркинга (25.01.2017, Москва) Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)Andrey Akinshin
 
Продолжаем говорить про арифметику
Продолжаем говорить про арифметикуПродолжаем говорить про арифметику
Продолжаем говорить про арифметикуAndrey Akinshin
 
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)Andrey Akinshin
 
Поговорим про арифметику
Поговорим про арифметикуПоговорим про арифметику
Поговорим про арифметикуAndrey Akinshin
 
Подружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project RiderПодружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project RiderAndrey Akinshin
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Andrey Akinshin
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядомAndrey Akinshin
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийAndrey Akinshin
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Практические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийПрактические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийAndrey Akinshin
 
Поговорим о различных версиях .NET
Поговорим о различных версиях .NETПоговорим о различных версиях .NET
Поговорим о различных версиях .NETAndrey Akinshin
 
Основы работы с Git
Основы работы с GitОсновы работы с Git
Основы работы с GitAndrey Akinshin
 
Сборка мусора в .NET
Сборка мусора в .NETСборка мусора в .NET
Сборка мусора в .NETAndrey Akinshin
 
Об особенностях использования значимых типов в .NET
Об особенностях использования значимых типов в .NETОб особенностях использования значимых типов в .NET
Об особенностях использования значимых типов в .NETAndrey Akinshin
 

Plus de Andrey Akinshin (20)

Поговорим про performance-тестирование
Поговорим про performance-тестированиеПоговорим про performance-тестирование
Поговорим про performance-тестирование
 
Сложности performance-тестирования
Сложности performance-тестированияСложности performance-тестирования
Сложности performance-тестирования
 
Сложности микробенчмаркинга
Сложности микробенчмаркингаСложности микробенчмаркинга
Сложности микробенчмаркинга
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про память
 
Кроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLRКроссплатформенный .NET и как там дела с Mono и CoreCLR
Кроссплатформенный .NET и как там дела с Mono и CoreCLR
 
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
 Теория и практика .NET-бенчмаркинга (25.01.2017, Москва) Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
Теория и практика .NET-бенчмаркинга (25.01.2017, Москва)
 
Продолжаем говорить про арифметику
Продолжаем говорить про арифметикуПродолжаем говорить про арифметику
Продолжаем говорить про арифметику
 
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
Теория и практика .NET-бенчмаркинга (02.11.2016, Екатеринбург)
 
Поговорим про арифметику
Поговорим про арифметикуПоговорим про арифметику
Поговорим про арифметику
 
Подружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project RiderПодружили CLR и JVM в Project Rider
Подружили CLR и JVM в Project Rider
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 
.NET 2015: Будущее рядом
.NET 2015: Будущее рядом.NET 2015: Будущее рядом
.NET 2015: Будущее рядом
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Распространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложенийРаспространённые ошибки оценки производительности .NET-приложений
Распространённые ошибки оценки производительности .NET-приложений
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Практические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложенийПрактические приёмы оптимизации .NET-приложений
Практические приёмы оптимизации .NET-приложений
 
Поговорим о различных версиях .NET
Поговорим о различных версиях .NETПоговорим о различных версиях .NET
Поговорим о различных версиях .NET
 
Основы работы с Git
Основы работы с GitОсновы работы с Git
Основы работы с Git
 
Сборка мусора в .NET
Сборка мусора в .NETСборка мусора в .NET
Сборка мусора в .NET
 
Об особенностях использования значимых типов в .NET
Об особенностях использования значимых типов в .NETОб особенностях использования значимых типов в .NET
Об особенностях использования значимых типов в .NET
 

Dernier

Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfJayanti Pande
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajanpragatimahajan3
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...EduSkills OECD
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationnomboosow
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityGeoBlogs
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfAdmir Softic
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsTechSoup
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Krashi Coaching
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...fonyou31
 
Student login on Anyboli platform.helpin
Student login on Anyboli platform.helpinStudent login on Anyboli platform.helpin
Student login on Anyboli platform.helpinRaunakKeshri1
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxheathfieldcps1
 
Grant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingGrant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingTechSoup
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdfSoniaTolstoy
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfciinovamais
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introductionMaksud Ahmed
 
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...PsychoTech Services
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeThiyagu K
 

Dernier (20)

Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdf
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajan
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communication
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activity
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
 
Student login on Anyboli platform.helpin
Student login on Anyboli platform.helpinStudent login on Anyboli platform.helpin
Student login on Anyboli platform.helpin
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
 
Grant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingGrant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy Consulting
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...
IGNOU MSCCFT and PGDCFT Exam Question Pattern: MCFT003 Counselling and Family...
 
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and Mode
 

Низкоуровневые оптимизации .NET-приложений

  • 1. Íèçêîóðîâíåâûå îïòèìèçàöèè .NET-ïðèëîæåíèé Àíäðåé Àêèíüøèí Áàðíàóëüñêîå ñîîáùåñòâî .NET ðàçðàáîò÷èêîâ bug.ineta.ru www.facebook.com/groups/dotnetbarnaul/
  • 2. Îïòèìèçèðîâàòü èëè íå îïòèìèçèðîâàòü? Premature optimization is the root of all evil. c Donald Ervin Knuth
  • 3. Ïðàâèëüíûé ïîäõîä Õîðîøèå àëãîðèòìû Õîðîøèå ñòðóêòóðû äàííûõ Ìàëîå êîëè÷åñòâî òÿæ¼ëûõ îïåðàöèé
  • 5. Memory traffic Memory traffic ýòî ïëîõî. Ìíîãî îáúåêòîâ ! GC òÿæåëî. Ðàçíàÿ öåíà îáúåêòîâ â Gen0, Gen1, Gen2, LOH. Ëèøíèé memory traffic: LINQ, óïàêîâêà, áîëüøèå îáúåêòû, îòñóòñòâèå èíòåðíèðîâàíèÿ è ïóëîâ îáúåêòîâ è ìíîãîå äðóãîå.
  • 6. Memory traffic: çàìûêàíèÿ void Foo(Funcint, int inc) { } void Run() { int y = 1; Foo(x = x + y); }
  • 7. Memory traffic: çàìûêàíèÿ private void Foo(Funcint, int inc) {} private void Run() { Program.c__DisplayClass1 cDisplayClass1 = new Program.c__DisplayClass1(); cDisplayClass1.y = 1; this.Foo(new Funcint, int((object) cDisplayClass1, __methodptr(b__0))); } [CompilerGenerated] private sealed class c__DisplayClass1 { public int y; public c__DisplayClass1() { base..ctor(); } public int Runb__0(int x) { return x + this.y; } }
  • 8. Memory traffic: çàìûêàíèÿ void Foo(Funcobject before, Funcobject after) { before(); // Some logic after(); } void Run() { var a = new object(); var b = new object(); Foo(() = a, () = b); }
  • 9. Memory traffic: çàìûêàíèÿ private void Run() { Program.c__DisplayClass2 cDisplayClass2 = new Program.c__DisplayClass2(); cDisplayClass2.a = new object(); cDisplayClass2.b = new object(); this.Foo(new Funcobject((object) cDisplayClass2, __methodptr(Runb__0)), new Funcobject((object) cDisplayClass2, __methodptr(Runb__1))); } [CompilerGenerated] private sealed class c__DisplayClass2 { public object a; public object b; public c__DisplayClass2() { base..ctor(); } public object Runb__0() { return this.a; } public object Runb__1() { return this.b; } }
  • 10. Memory traffic: çàìûêàíèÿ void Foo(Funcint, int inc) { } static int y = 1; static int StaticInc(int x) { return x + y; } void Run() { Foo(x = StaticInc(x)); Foo(StaticInc); }
  • 11. Memory traffic: çàìûêàíèÿ private void Run() { if (Program.CS$9__CachedAnonymousMethodDelegate1 == null) { Program.CS$9__CachedAnonymousMethodDelegate1 = new Funcint, int((object) null, __methodptr(Runb__0)); } this.Foo(Program.CS$9__CachedAnonymousMethodDelegate1); this.Foo(new Funcint, int((object) null, __methodptr(StaticInc))); } [CompilerGenerated] private static int Runb__0(int x) { return Program.StaticInc(x); } [CompilerGenerated] private static Funcint, int CS$9__CachedAnonymousMethodDelegate1;
  • 12. Memory traffic: params void Foo(params int[] x) { } void Main() { Foo(); // IL_0001: ldarg.0 // IL_0002: ldc.i4.0 // IL_0003: newarr // IL_0008: call }
  • 13. Memory traffic: yeild IEnumerableint Foo() { for (int i = 0; i 5; i++) yield return i; }
  • 14. Memory traffic: yield private IEnumerableint Foo() { Program.Food__0 fooD0 = new Program.Food__0(-2); fooD0.4__this = this; return (IEnumerableint) fooD0; } [CompilerGenerated] private sealed class Food__0 : IEnumerableint, IEnumerable, CIEnumeratorint, IEnumerator, IDisposable { private int 2__current; private int 1__state; private int l__initialThreadId; public int i5__1; public Program 4__this; ...
  • 15. Memory traffic: List vs IList void Foo1(Listint list) { var start = GC.GetTotalMemory(true); foreach (var i in list) Console.WriteLine(GC.GetTotalMemory(true) - start); } void Foo2(IListint list) { var start = GC.GetTotalMemory(true); foreach (var i in list) Console.WriteLine(GC.GetTotalMemory(true) - start); } void Run() { var list = new Listint { 1 }; Foo1(list); Foo2(list); }
  • 16. Memory traffic: ìàëåíüêèé List struct SmallListT : IListT { private T item1; private T item2; private T item3; private ListT otherItems; public ListT ToList() { ... } }
  • 17. Ìèêðîáåí÷ìàðêè Òðåáîâàíèÿ: Ïîëó÷åíèå ìåòðèê Âîñïðîèçâîäèìîñòü Îáúåêòèâíîñòü Îòñóòñòâèå ñàéä-ýôôåêòîâ
  • 18. Êàê çàïóñêàòü áåí÷ìàðê? Release mode Without debugging Ïðîãðåâ Çàïóñê íà îäíîì ÿäðå ×èñòîå îêðóæåíèå Ìíîãîêðàòíûé çàïóñê â ðàçíûõ îêðóæåíèÿõ
  • 19. Íóæíî ïîìíèòü ïðî: Dead code elmintation Inlining Folding Branch prediction 600+ äðóãèõ îïòèìèçàöèé
  • 20. Interface implementation interface IFoo { int Inc(int x); } class FastFoo : IFoo { public int Inc(int x) { return x + 1; } } class SlowFoo : IFoo { public int Inc(int x) { return 1 + x; } } void DoIt(IFoo foo) { for (int i = 0; i 1000000000; i++) foo.Inc(0); } DoIt(new FastFoo()); DoIt(new SlowFoo());
  • 21. Readonly fields public struct Int256 { private readonly long bits0, bits1, bits2, bits3; public Int256(long bits0, long bits1, long bits2, long bits3) { this.bits0 = bits0; this.bits1 = bits1; this.bits2 = bits2; this.bits3 = bits3; } public long Bits0 { get { return bits0; } } public long Bits1 { get { return bits1; } } public long Bits2 { get { return bits2; } } public long Bits3 { get { return bits3; } } } class Test { private readonly Int256 value; // private Int256 value; public Test() { value = new Int256(1L, 5L, 10L, 100L); } public long TotalValue { get { return value.Bits0 + value.Bits1 + value.Bits2 + value.Bits3; } } public void RunTest() { var sample = TotalValue; Stopwatch sw = Stopwatch.StartNew(); long total = 0; for (int i = 0; i 1000000000; i++) total += TotalValue; sw.Stop(); Console.WriteLine(Total time: {0}ms, sw.ElapsedMilliseconds); } static void Main() { new Test().RunTest(); } } c Jon Skeet, Micro-optimization: the surprising inefficiency of readonly fields
  • 22. Îñòîðîæíåå ñ ÎÎÏ! Êðàñèâûé äèçàéí íå âñåãäà ñî÷åòàåòñÿ ñ âûñîêîé ïðîèçâîäèòåëüíîñòüþ.
  • 23. Reflection static MemoryLeakFixer() { var fields = typeof(DisposableObject).GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); fieldInfo = fields.FirstOrDefault(f = f.FieldType == typeof(GCHandle)); } public static void FixAfterRelease(DisposableObject obj) { if (obj.IsDisposed) { var dataHandle = (GCHandle)fieldInfo.GetValue(obj); if (dataHandle.IsAllocated) dataHandle.Free(); } }
  • 24. StructLayout [StructLayout(LayoutKind.Explicit)] struct MyStruct { [FieldOffset(0)] public Int16 Value; [FieldOffset(0)] public Byte LowByte; } var s = new MyStruct(); s.Value = 256 + 100; Console.WriteLine(s.LowByte); // 100
  • 25. ×¼ðíàÿ ìàãèÿ public class MyObject { public long X; } public class Pumpkin { public int Y1; public int Y2; } public unsafe IntPtr GetAddress(object obj) { var typedReference = __makeref(obj); return *(IntPtr*)(typedReference); } public unsafe T ConvertT(IntPtr address) { var fakeInstance = default(T); var typedReference = __makeref(fakeInstance); *(IntPtr*)(typedReference) = address; return __refvalue( typedReference,T); } public void Run() { var myObject = new MyObject { X = 1 + (2L 32) }; var pumpkin = ConvertPumpkin(GetAddress(myObject)); Console.WriteLine(pumpkin.Y1 + + pumpkin.Y2); // 1 2 myObject.X = 3 + (4L 32); Console.WriteLine(pumpkin.Y1 + + pumpkin.Y2); // 3 4 }
  • 26. Íóæíî ïîíèìàòü // sscli20clrsrcvmtypehandle.h // A TypeHandle is the FUNDAMENTAL concept of type identity in the CLR. // That is two types are equal if and only if their type handles // are equal. A TypeHandle, is a pointer sized struture that encodes // everything you need to know to figure out what kind of type you are // actually dealing with. // At the present time a TypeHandle can point at two possible things // // 1) A MethodTable (Intrinsics, Classes, Value Types and their instantiations) // 2) A TypeDesc (all other cases: arrays, byrefs, pointer types, // function pointers, generic type variables) // // or with IL stubs, a third thing: // // 3) A MethodTable for a native value type.
  • 27. Íóæíî ïîíèìàòü private void Print(Type type) { bool isTypeDesc = ((int)type.TypeHandle.Value 2) 0; Console.WriteLine({0}: {1} = {2}, type.Name.PadRight(10), type.TypeHandle.Value.ToString(X), (isTypeDesc ? TypeDesc : MethodTable)); } private void Run() { Print(typeof(int)); Print(typeof(object)); Print(typeof(Stream)); Print(typeof(int[])); Print(typeof(int[][])); Print(typeof(object[])); } // Int32 : 65C4C480 = MethodTable // Object : 65C4B060 = MethodTable // Stream : 65C4D954 = MethodTable // Int32[] : 65854C8A = TypeDesc // Int32[][] : 658F6BD6 = TypeDesc // Object[] : 65854D7A = TypeDesc
  • 28. Öèêëû public int Foo997() { int sum = 0; for (int i = 0; i 997; i++) sum += a[i]; return sum; } public int Foo1000() { int sum = 0; for (int i = 0; i 1000; i++) sum += a[i]; return sum; }
  • 30. Ïàðàëëåëèçì èíñòðóêöèé int iterationCount = 256 * 1024 * 1024; int[] a = new int[2]; for (int i = 0; i iterationCount; i++) { a[0]++; a[0]++; } for (int i = 0; i iterationCount; i++) { a[0]++; a[1]++; }
  • 31. Êýø ïðîöåññîðà int[] x = new int[64 * 1024 * 1024]; for (int i = 0; i x.Length; i++) x[i] *= 3; for (int i = 0; i x.Length; i += 16) x[i] *= 3;
  • 32. Êýø ïðîöåññîðà Óìíîæåíèå ìàòðèö: // Standard for (k = 0; k n; k++) for (i = 0; i n; i++) for (j = 0; j n; j++) c[k][i] = c[k][i] + a[k][j]*b[j][i]; // Optimized for (k = 0; k n; k++) for (i = 0; i n; i++) for (j = 0; j n; j++) c[i][j] = c[i][j] + a[i][k]*b[k][j];
  • 36. Êýø ïðîöåññîðà False sharing private const int Step = 1; private static int[] x = new int[1024]; private void Foo(int p) { for (int j = 0; j 1000000000; j++) x[p] = x[p] + 3; } private void Run() { var s = Stopwatch.StartNew(); var tasks = new Task[4]; tasks[0] = Task.Factory.StartNew(() = Foo(0 * Step)); tasks[1] = Task.Factory.StartNew(() = Foo(1 * Step)); tasks[2] = Task.Factory.StartNew(() = Foo(2 * Step)); tasks[3] = Task.Factory.StartNew(() = Foo(3 * Step)); Task.WaitAll(tasks); Console.WriteLine(s.ElapsedMilliseconds); } À òåïåðü ïîäóìàéòå ïðî CardTable...