Znalazłem jedno nieprzyjemne zachowanie rozwijające się w Visual Studio. To wisiało na mojej maszynie podczas kompilacji C#.Kompresowanie pamięci kompilatora C# (csc.exe) kompilujące typy zagnieżdżone i Linq
mam zmniejszone zachowanie do następnego kodu minimalnym źródłowego
using System.Collections.Generic;
using System.Linq;
namespace memoryOverflowCsharpCompiler {
class SomeType { public decimal x; }
class TypeWrapper : Dictionary<int,
Dictionary<int,
Dictionary<int, SomeType [] []>>> {
public decimal minimumX() {
return base.Values.Min(a =>
a.Values.Min(b =>
b.Values.Min(c =>
c .Sum(d =>
d .Sum(e => e.x)))));
}
}
}
kompilacji z
PROMPT> csc source.cs
*** BANG! overflow memory usage (up to ~3G)
PROMPT> csc /?
Microsoft (R) Visual C# Compiler version 12.0.30501.0
Copyright (C) Microsoft Corporation. All rights reserved.
...
(używając Windows 8.1 Pro N 64; csc
proces kompilator jest uruchomiony z 32bits)
drastyczne modyfikacje nie powodują takiego zachowania (np. zmiana decimal
przez int
, zmniejszając jeden zagnieżdżony leve l, ...), wykonując wielki Select
następnie redukcji, działa dobrze
Explicit Obejście:
return base.Values.SelectMany(a =>
a.Values.SelectMany(b =>
b.Values.Select (c =>
c. Sum (d =>
d. Sum (e => e.x))))).Min();
Mimo to jawne obejście istnieje, to nie gwarantuje, że takie zachowanie nie powtórzy.
Co jest nie tak?
Dziękujemy!
z odsetek, próbowałeś to z podglądem VS2015 ? Byłoby ciekawie wiedzieć, czy jest to ustalone w Roslyn. –
Ten kod ma kilka rzeczy, które utrudniają wnioskowanie o typach: 1) Niejawne konwersje 2) Wiele przeciążeń 3) zagnieżdżonych lambd. Jeśli spróbujesz wystarczająco mocno, możesz zakodować NP pełne problemy SAT w tych, więc kompilator nie może skutecznie rozwiązać wszystkich problemów z przeciążeniem + rozwiązywanie problemów typu. Ale nie wiem, dlaczego twój przykład jest taki zły. – CodesInChaos
@JonSkeet Każdy wolontariusz? (Nie mogę) Szukałem o tym, ale nie znaleziono :( – josejuan