Что-то подзабросил я
сериюАвтор: Sinix
Дата: 10.05.16
. Исправляем
Спонсор сегодняшнего поста —
stackoverflow (спойлеры по ссылке).
| код |
| static class Program
{
struct ValueHolder
{
private readonly long _value;
public ValueHolder(long value)
{
_value = value;
}
}
struct ValueHolderNullable
{
private readonly long? _value;
public ValueHolderNullable(long? value)
{
_value = value;
}
}
static void Main(string[] args)
{
Console.WindowWidth = 120;
var data = Enumerable.Range(0, 10000)
.Select(i => (long)i % 1000)
.ToArray();
var data2 = data.Select(l => new ValueHolder(l)).ToArray();
var data3 = data.Select(l => new ValueHolderNullable(l)).ToArray();
// Замеры начались
Measure("Raw", () =>
{
data.Distinct().ToArray();
return data.Length;
});
Measure("Wrapper", () =>
{
data2.Distinct().ToArray();
return data2.Length;
});
Measure("NullableWrapper", () =>
{
data3.Distinct().ToArray();
return data3.Length;
});
// Замеры закончились
Console.WriteLine("Done.");
Console.ReadKey();
}
static void Measure(string name, Func<long> callback)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
var mem = GC.GetTotalMemory(true);
var gc00 = GC.CollectionCount(0);
var gc01 = GC.CollectionCount(1);
var gc02 = GC.CollectionCount(2);
var sw = Stopwatch.StartNew();
var result = callback();
sw.Stop();
var mem2 = GC.GetTotalMemory(false);
var gc10 = GC.CollectionCount(0);
var gc11 = GC.CollectionCount(1);
var gc12 = GC.CollectionCount(2);
var memDelta = (mem2 - mem) / 1024.0;
var gcDelta0 = gc10 - gc00;
var gcDelta1 = gc11 - gc01;
var gcDelta2 = gc12 - gc02;
Console.WriteLine(
"{0,20}: {1,5}ms, ips: {2,22:N} | Mem: {3,9:N2} kb, GC 0/1/2: {4}/{5}/{6} => {7,6}",
name, sw.ElapsedMilliseconds, result / sw.Elapsed.TotalSeconds, memDelta, gcDelta0, gcDelta1, gcDelta2, result);
}
}
|
| |
| вывод (для нетерпеливых) |
| Raw: 2ms, ips: 3 674 849,33 | Mem: 84,02 kb, GC 0/1/2: 0/0/0 => 10000
Wrapper: 5ms, ips: 1 958 288,46 | Mem: 519,83 kb, GC 0/1/2: 0/0/0 => 10000
NullableWrapper: 2759ms, ips: 3 623,46 | Mem: 655,90 kb, GC 0/1/2: 229/0/0 => 10000
Done.
|
| |
Вопрос обычный: как так-то?
Здравствуйте, Sinix, Вы писали:
S>Вопрос обычный: как так-то?
Привет дефолтовому компареру? Если Equals и GetHashCode переопределить, то все сразу становится хорошо.
Upd: почитал тред на SO. Веселуха, однако.
Получается, что дефолтовая реализация GetHashCode забивает на реализацию в Nullable<T> и считает все по своему.
Это реально WTF.
Здравствуйте, hardcase, Вы писали:
H>Вот только не все структуры предназначены для использования в виде ключей. Я обычно поступаю от использования: как только необходимо структуру пихнуть в Set или Dictionary, выясняю реализует ли она IEquatable.
+1. Но это справедливо для непубличных типов. Для public-структур лучше подстраховаться. Спасиб что напомнили, сейчас
подарю ещё парочку WTFАвтор: Sinix
Дата: 16.09.16
.