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: 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() { ... }
}
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.
Öèêëû
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];