Столкнулся с такой проблемой, есть класс, который создается с помощью CodeDom (порядка 90 000 строк). Создаю его экземпляр. При попытке вызвать метод инициализации приложение виснет на 5 секунд и после этого выполняется метод. При чем такое поведение как в релизе, так и в дебаге. При переходе в тело метода "InitMethods()" через студию такая же ситуация.
Вопрос, что происходит с CLR или JIT? Где это можно посмотреть и как? Профайлер показывает, что метод выполняется 15 миллисекунд, все остальное время непонятно на что тратится.
Далее код:
Базовый класс для класса значений:
public abstract class ValueBase<TValue>
{
}
Интерфейс для класса значений:
public interface IParamValue
{
void InitValue(object value);
}
Класс значений:
public class ParamValueDouble : ValueBase<double>, IParamValue
{
public void InitValue(object value)
{
}
}
Базовый класс для генерируемого класса:
public class Base<TValueType,TValue>
{
public delegate TValueType GetValue();
protected Dictionary<string, Dictionary<DateTime, GetValue>> calculateMethods;
}
Сам генерируемый класс (у меня 11000 методов вида P1 — P11000):
public class calculate : Base<ParamValueDouble, double>
{
public ParamValueDouble P1()
{
return 0;
}
//и т.д.public void InitMethods()
{
calculateMethods = new Dictionary<string, Dictionary<DateTime, GetValue>>();
methods = new Dictionary<DateTime, GetValue>();
methods.Add(new DateTime(...), P1);
calculateMethods.Add("Code1", methods);
//и т.д.
}
}
При вызове метода InitMethods, приложение виснет на 20 секунд, есть идеи? Пока решил переделать (не удалось).
На JIT я бы думал одним из последних. Прежде всего под подозрением статические конструкторы всех используемых в этом методе классов. Поставь исключение в конце этого метода, подключи профайлер, и посмотри.
Здравствуйте, hi_octane, Вы писали:
_>На JIT я бы думал одним из последних. Прежде всего под подозрением статические конструкторы всех используемых в этом методе классов. Поставь исключение в конце этого метода, подключи профайлер, и посмотри.
Я создал экземпляр, при попытке зайти в тело метода по F11 студия виснет на 5 секунд. Статики вообще нет ни какой. DotTrace показывает общее выполнение main() — 5560 миллисекунд, вызов конструктора — 3 миллисекунды, выполнение метода 15 миллисекунд. Кроме трех строк больше в профайлере ничего нет.
Здравствуйте, GrishaCo, Вы писали:
GC>Я создал экземпляр, при попытке зайти в тело метода по F11 студия виснет на 5 секунд.
Компилятор обычно виснет для вычисления значений в открытых окнах. Локальных переменных или просто watch, а может и обзор памяти открыт, но это врядли. В .Нет они эту проблему решили тем что все эти значения подгружаются асинхронно и параллельно по отношению к юай.
Здравствуйте, vf, Вы писали:
vf>Здравствуйте, GrishaCo, Вы писали:
GC>> calculateMethods.Add("Code1", methods); GC>> //и т.д.
vf>Вероятно все 10000 методов компилирует?! Вообще jit как-то не заточен под большие методы и классы, я например сталкивался с такой проблемой
Проблема в том, что у меня есть аналогичный класс только без генериков, создание его экземпляра и выполнение метода происходит за едва заметное время. По поставленной задаче пришлось ввести генерики и появилась вот такая проблема. Бьюсь уже с ней пять дней все без толку. При этом даже посмотреть некуда, просто выкидываю часть функционала, т.е. заменяю более простым, но пока результата нет. Боюсь придется держать два (пока) одинаковых класса.
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, GrishaCo, Вы писали:
GC>>Я создал экземпляр, при попытке зайти в тело метода по F11 студия виснет на 5 секунд.
C>Компилятор обычно виснет для вычисления значений в открытых окнах. Локальных переменных или просто watch, а может и обзор памяти открыт, но это врядли. В .Нет они эту проблему решили тем что все эти значения подгружаются асинхронно и параллельно по отношению к юай.
Дело в том, что этот класс создается на сервере (аля класс вычислений), т.е. UI здесь вообще нет, только через CodeDom создается класс, компилится, дергается из сборки тип и происходит создание его экземпляра. Вот тут и засада. Кстати есть аналогичный класс но без генериков, так вот он создается и выполняет метод за почти не заметное время.
Здравствуйте, Spinifex, Вы писали:
S>Чтобы убедиться, что дело именно в JIT попробуйте воспользоваться ngen.exe. Может дело действительно в инициализаторах типов, либо особенностях кода.
Здравствуйте, GrishaCo, Вы писали:
GC>При вызове метода InitMethods, приложение виснет на 20 секунд, есть идеи? Пока решил переделать (не удалось).
Обычно такие плюхи бывают когда загружаешь подписанные сборки. Среда не может их проверить мгновенно, в силу отсутсвия интернета или его высокой латентности. Исправляется отключением проверки подписей сборок (по умолчанию включено) http://www.rsdn.ru/forum/dotnet/4034440.1
Здравствуйте, GrishaCo, Вы писали:
GC>Всем доброго времени суток!
GC>Столкнулся с такой проблемой, есть класс, который создается с помощью CodeDom (порядка 90 000 строк). Создаю его экземпляр. При попытке вызвать метод инициализации приложение виснет на 5 секунд и после этого выполняется метод. При чем такое поведение как в релизе, так и в дебаге. При переходе в тело метода "InitMethods()" через студию такая же ситуация.
GC>Вопрос, что происходит с CLR или JIT? Где это можно посмотреть и как? Профайлер показывает, что метод выполняется 15 миллисекунд, все остальное время непонятно на что тратится.
Здравствуйте, alexanderfedin, Вы писали:
A>Здравствуйте, GrishaCo, Вы писали:
GC>>Всем доброго времени суток!
GC>>Столкнулся с такой проблемой, есть класс, который создается с помощью CodeDom (порядка 90 000 строк). Создаю его экземпляр. При попытке вызвать метод инициализации приложение виснет на 5 секунд и после этого выполняется метод. При чем такое поведение как в релизе, так и в дебаге. При переходе в тело метода "InitMethods()" через студию такая же ситуация.
GC>>Вопрос, что происходит с CLR или JIT? Где это можно посмотреть и как? Профайлер показывает, что метод выполняется 15 миллисекунд, все остальное время непонятно на что тратится.
A>Code Explosion
? A>If you use Value-types to specialize generics, this might be the case, as JIT re-generates a big bunch of native code for that exact specialization.
Спасибо за ответ.
Но возникает резонный вопрос, почему при сборке проекта в одну из платформ (x86|x64) проблема исчезает? JIT компилятор ведет себя по другому в зависимости от платформы или при сборке под конкретную платформу заранее известны все Value-типы и по этому JIT компиляция идет намного быстрее?