Всем привет!
В дополнение к серии на тему различных WTF, начатаю ув. Sinix
Итак. Даны 2 примера кода:
[MethodImpl(MethodImplOptions.NoInlining)]
public static int GetNumber_1(object value)
{
var v = value as int?;
if (v != null)
return v.GetValueOrDefault();
return 0;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int GetNumber_2(object value)
{
if (value is int)
return (int)value;
return 0;
}
Что здесь не так? Оба кода делают одно и тоже — возвращают забоксенное значение в случае, если там
int и
0 в противном случае.
| Код для проверки предположений (запускать без отладчика, Ctrl-F5): |
| using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
public static class Program
{
public const int Count = 100 * 1000 * 1000;
[MethodImpl(MethodImplOptions.NoInlining)]
public static int GetNumber_1(object value)
{
var v = value as int?;
if (v != null)
return v.GetValueOrDefault();
return 0;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int GetNumber_2(object value)
{
if (value is int)
return (int)value;
return 0;
}
public static void Main()
{
var a = (object)0;
GetNumber_1(a);
GetNumber_2(a);
Measure("Get number via: as int?", () =>
{
var x = a;
for (var i = 0; i < Count; i++)
{
GetNumber_1(x);
}
});
Measure("Get number via: is int ", () =>
{
var x = a;
for (var i = 0; i < Count; i++)
{
GetNumber_2(x);
}
});
}
private static void Measure(string name, Action action)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var sw = Stopwatch.StartNew();
action();
sw.Stop();
Console.WriteLine("{0,20}: {1,5} ms, ips: {2,15:N}", name, sw.ElapsedMilliseconds, Count / sw.Elapsed.TotalSeconds);
}
}
}
|
| |
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>