Re[48]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: fddima  
Дата: 15.08.13 14:40
Оценка: +1
Здравствуйте, artelk, Вы писали:

A>Ну давай, успокой общественность, найди в тесте ошибку.

A>У меня примерно те же числа при нескольких запусках.
Я их не читал. Просто от оборудования результаты сильно могут зависить на микротесте.
Re[48]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: artelk  
Дата: 15.08.13 14:52
Оценка:
Здравствуйте, fddima, Вы писали:

F>Здравствуйте, artelk, Вы писали:


A>>Все равно Delegate быстрее...

F>А у меня наоборот.
F>MyFunction — Direct: -2377[/q]
Это понятно, т.к. direct тут не совсем direct.

F>Делегат может быть быстрее.

За счет чего?

F>Но затраты на его создание, афаик, довольно большие.

Я его создаю за пределами цикла.
Сделал, чтоб создавалось каждый раз:
//...
for (int j = 0; j < N; j++)
{
    myDelegate = p.Work;
    myDelegate(1);
}
//...
for (int j = 0; j < N; j++)
{
    myFunction = new MyFunction(p);
    myFunction.Invoke(1);
}
//...

Результаты:

Direct: 65322
Delegate: 275326
MyFunction: 245319
Delegate — Direct: 210004
MyFunction — Direct: 179997


Да, создается заметно дольше.

F>В любом случае на таком микротесте понятно не будет. + разбор процессоров по всей видимости дают разные результаты.

А на каком будет понятно?
Re[49]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: fddima  
Дата: 15.08.13 15:31
Оценка: +1
Здравствуйте, artelk, Вы писали:

F>>Делегат может быть быстрее.

A>За счет чего?
За счет того, что никакого диспатчинга не происходит. Делегат — это this и массив готовых указателей на методы. Ну и их хорошенько оптимизировали в .net 2+, если память не изменяет.

F>>Но затраты на его создание, афаик, довольно большие.

A>Я его создаю за пределами цикла.
Это понятно. На практике можем просто иметь метод с единоразовым созданием делегата vs создать класс и вызывать виртуальный метод. Что будет в общем зачете эффективнее — сложно судить.

F>>В любом случае на таком микротесте понятно не будет. + разбор процессоров по всей видимости дают разные результаты.

A>А на каком будет понятно?
Как найти эту золотую середину простым сбособом за 5 минут — мне, увы, не известно. Особенно, когда имеем такие противоречивые результаты. Ничего лучше профилирования двух подходов на более крупных задачах — я не знаю. Наверное самый простой способ сделать это — научить компилятор использовать делегаты — а это задача нифига не тривиальная.
Re[48]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: artelk  
Дата: 15.08.13 16:10
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, fddima, Вы писали:


F>>Delegate — Direct: -2055

A>Ну давай, успокой общественность, найди в тесте ошибку.
A>У меня примерно те же числа при нескольких запусках.

Для direct дополнительно происходит копирование "p" в стеке. Видимо, этого оказалось достаточно, чтобы direct оказался медленнее.

Я обманул, x64 — это операционка, а сбилдил я под any cpu (забыв убрать Prefer 32, поэтому запускалось как WoW64).
Поменял на x64:
1.

Direct: 74636
Delegate: 72299
MyFunction: 72307
Delegate — Direct: -2337
MyFunction — Direct: -2329



2.
Если пересоздавать делегат и myFunction на каждой итерации:

Delegate: 372441
MyFunction: 296651


3.
Если не пересоздавать, но заменить делегат на "n => p.Work(n)"

Delegate: 109622
MyFunction: 74634


4.
Если при этом еще и пересоздавать на каждой итерации (делегат пересоздавать как "n => p.Work(n)"):

Delegate: 125970
MyFunction: 301498


В 4м случае, видимо, сработал оптимизатор и пересоздание выкинул, поэтому делегат сработал быстрее.
В 2м случае оптимизации не произожло, т.к. method group, а его (по спецификации) нельзя кэшировать.
3й результат ожидаем, хотя я думал, что различие будет более существенным.
1й результат показывает, что вызов method group работает со скоростью виртуального метода!
Re[50]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: artelk  
Дата: 15.08.13 16:49
Оценка:
Здравствуйте, fddima, Вы писали:

F>Здравствуйте, artelk, Вы писали:


F>>>Делегат может быть быстрее.

A>>За счет чего?
F> За счет того, что никакого диспатчинга не происходит. Делегат — это this и массив готовых указателей на методы. Ну и их хорошенько оптимизировали в .net 2+, если память не изменяет.
Work — невиртуальный метод, никакого диспатчинга нет.
А оптимизируют с каждой новой версией .Net.
Возможно, уже имеет смысл переходить на делегаты в компиляторе. Т.е. утверждение, что делегаты тормознее перестает быть правдой...
Re[51]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: fddima  
Дата: 15.08.13 19:32
Оценка: 8 (1)
Здравствуйте, artelk, Вы писали:

F>>>>Делегат может быть быстрее.

A>>>За счет чего?
F>> За счет того, что никакого диспатчинга не происходит. Делегат — это this и массив готовых указателей на методы. Ну и их хорошенько оптимизировали в .net 2+, если память не изменяет.
A>Work — невиртуальный метод, никакого диспатчинга нет.
Function.Invoke — виртуальный. Например, имеем классы A->B->C с неким виртуальным методом apply.
Как только мы сделаем делегат на какой-то конкретный метод, конкретного типа — нас не будет волновать виртуальность метода, — банально, есть this, и есть адрес какой позвать. Махинации со стёком ещё остаются, в случае делегатов, может там чего и оптимизировали — но практика как раз показывает, что они дешевле, чем виртуальность.
Т.е., имея виртульный метод — рантайм фактически всегда обязан разобраться какой же именно метод нужно позвать (при каждом вызове). При чём в общем случае — даже sealed не способен помочь, — мы обычно как раз принимаем базовый тип на входе (некий Function) — так что от виртуальности никак не избавится. Теоретически, можно lookup нужного метода вынести за пределы цикла, но это будет работать только на циклах, и я очень сомневаюсь, что такая оптимизация производится — JIT на самом деле генерирует очень прямолинейный код (ну или так было). Именно поэтому делегаты всегда побеждают в циклах. Но... (читаем дальше)

A>А оптимизируют с каждой новой версией .Net.

A>Возможно, уже имеет смысл переходить на делегаты в компиляторе. Т.е. утверждение, что делегаты тормознее перестает быть правдой...
Оно перестало быть правдой давно. Но это всё, всё равно ерунда, — различия они минимальны. Получить 20-50% разницы на миллиарде! фактически пустых вызовов — ну действительно пофигу. Там где они не минимальны (коллекции с кастомным компаратором, например) — должен быть полноценный инлайнинг, а не какие-то там косвенные вызовы — и делегаты и виртуальные вызовы — работают одинаково плохо в таких случаях. Но этот самый полноценный инлайнинг даёт ощутимое преимущество разве, что специализированных коллекциях, и отлично пишутся на том же самом C# ручками. %) То, что в разных случаях более эффективны — разные подходы — я думаю понятно, но как только становится вопрос о взаимедействии между сборками — нам, просто необходима общая база. В случае N — это функциональный тип. В случае C# — делегаты. На самом деле подход в N к этому делу общеизвестен, прост и логичен, и как я понимаю, родился в эпоху когда не было стандартных Action/Func.
По сути в этой подветке кртикие подвергается не сам подход, а "недостаточная" оптимизация компилятора — т.е. при возможности, не генерировать класс-функтор вообще. При возможности — хорошо бы его объединять с объектом-замыканием (только, когда это возможно!). Ну ещё я бы отметил, отсутствие кеширование делегата, по тем же правилам как и у C#. Но, без этого жить наверное можно.
А качество кодогенератора — да — надо улучшать. Откровенно лишние слоты в методах, излишние stloc/ldloc, когда всё должно быть совершенно просто на стёке. От этого тоже растёт объем сборки кстати, и опять таки — не факт, что это JIT способен эффективно выбросить. А даже если он и может это выбросить — для JIT — это лишняя работа, а это в свою очередь тоже увеличивает startup time.

PS: Ну, где не прав — не обезсудьте.
Re[28]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.08.13 22:47
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Проект уже заморожен фактически.


Мечтать не вредно.

I>Почему меня интересует Немерле(в той части, что без макров) дело десятое.


Батхерт у тебя. Вот и бьешься ты в истошной боли.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 16.08.13 23:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ikemefula, Вы писали:


I>>Проект уже заморожен фактически.


VD>Мечтать не вредно.


Похоже это хроническое заболевание у немерлистов, не могут прочесть, что речь про мой проект, это он заморожен.

I>>Почему меня интересует Немерле(в той части, что без макров) дело десятое.


VD>Батхерт у тебя. Вот и бьешься ты в истошной боли.


Я вижу кому то батхерт мешает прочитать уже в который раз.
Re[24]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 10:58
Оценка: -1 :)
Здравствуйте, Ikemefula, Вы писали:

VD>>Это чушь. На фрагментацию влияет количество перезоемов больших объектов и паттерн распределения памяти.


I>Это факты.


Факты в студию, плиз. Или не трепись по чем зря.

>>А для загрузки длл отводится соврешенно другая область памяти, которая никак не влияет на область памяти выделяемой под LOH.


I>Чудеса, да и только.


Учи матчасть.

I>Какая область памяти отводится, дело десятое. Главное что сборки жрут именно ту часть АП, которая может использоваться GC.


Области резервируются при старте дотнета. Влиять на фрагментацию они не могут.

Да и смешно говорить о влиянии на фрагментацию нескольких килобайт. Ты двумя занятыми массивами фрагментируешь LOH куда больше.

Ты хоть в значение слова "фрагментация" вдумайся. Фрагменировать можно только что-то сплошное.

I>Проверить просто — берешь консольное приложение безо всяких зависимостей и выделяешь память. Выходит около 1.6-1.9 гб в завимости от размера блока. 1.9 будет если выделять кусками по 16мб


I>Дальше просто — вгружаешь сборки и, внезапно, когда количество и разным сборок сравнимо с количеством в реальном приложении, память почемуто начинается заканчиваться на планке 1гб+200мб. Все зависит естественно от способа расходования памяти.


Вот, блин, удивительно, да? Если занять 100 мег чем-то другим, то 100 мег окажется недоступным. Только причем тут фрагментация?

Если ты даже очень постараться немерловая сборка у тебя выйдет на 100 Кб больше аналогичной на шарпе. Это 100 Кб ты в микроскоп не заметишь. У IT вырожденный случай. Вызван он убогостью шарпа и нежеланием IT переписывать этот код (так как он объемный и работает). Если бы он писал код на Немерле изначально, то его сборка была бы не больше шарповской, а меньше, так как то что он эмулирует на лямбдах и делегатах можно было бы выразить макросами генерирующими эффективный низкоуровневый код.

I>У меня >50мб исходного кода. Ты хорошо понимаешь, что это значит ?


Ну, и? Они превратятся в ~50 длл-и. Объем занимаемой ими памяти один хрен не будет определяться размером ДЛЛ-и, а будет определяться объемом хранимых в памяти данных.

Кроме того это косвенный показатель того, что ты используешь экстенсивные методы — пишешь код руками. У нас вот код еденицами метров измеряется, но это мета-код. Он порождает уже очень много эффективного кода. Но так как мы его генерируем мы можем плевать на абстракции, инкапсуляцию и прочие заморочки нежные для рукописного кода. В итоге получается эффективный код жрущий минимум ресурсов. В ручную ты это просто задолжаться делать.

Короче тратить свое время на твое образование слишком расточительно. Все равно ты не слушаешь, а долдонишь одно и то же. Оставайся дальше упертым и ищи дальше фатальные недостатки в том, чего сам понять и освоить не можешь. Твои проблемы.

Как правильно сказал НН, если бы тебя реально заботила эффективность генерируемого немерлом кода, ты примкнул бы к нам и помог проекту. За одно свой уровень поднял бы. А у тебя другая задача — срач устроить. Но это без меня.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 11:09
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Я вижу кому то батхерт мешает прочитать уже в который раз.


Читать не чего особо. То что ты понаписал я прочел. Вывод один — батхерт и домыслы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 17.08.13 15:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>>>Это чушь. На фрагментацию влияет количество перезоемов больших объектов и паттерн распределения памяти.


I>>Это факты.


VD>Факты в студию, плиз. Или не трепись по чем зря.


Факты простые — сборка и код генереный компилятором, лежат в менеджед хипах. Странно, да ? Сборка, по моему, лежит в GC Heap, код — в JIT Heap. Для GC, это просто хипы, как и LOH, Loader Heap, Fast, Slow, COM-Heap и тд и тд и тд. Он со всеми умеет работаеть, только сценарии меняются.
Нет никакой особой области памяти, куда загружаются сборки. Нужна память — создаётся новый хип, если в старом память закончилась.

>>>А для загрузки длл отводится соврешенно другая область памяти, которая никак не влияет на область памяти выделяемой под LOH.

I>>Чудеса, да и только.
VD>Учи матчасть.

Да, да, кое кому не мешает подучить матчать, а по после откровения "просто задай своим сборкам базовый адрес загрузки отличный от остальных. Это заметно повысит скорость загрузки, кстати." твои слова всерьёз невозможно воспринимать. Каждый школьник знает, что один только JIT съест весь профит. Но все даже хуже — даже без джыта профит сложно получить.

I>>Какая область памяти отводится, дело десятое. Главное что сборки жрут именно ту часть АП, которая может использоваться GC.

VD>Области резервируются при старте дотнета. Влиять на фрагментацию они не могут.

Сборками можно выюзать хоть всю память и при этом "Влиять на фрагментацию они не могут". Ты точно это хотел сказать ?

VD>Да и смешно говорить о влиянии на фрагментацию нескольких килобайт. Ты двумя занятыми массивами фрагментируешь LOH куда больше.


Десятки, как минимум, мегабайт, вдруг стали килобайтами ? Ну-ну.

I>>Дальше просто — вгружаешь сборки и, внезапно, когда количество и разным сборок сравнимо с количеством в реальном приложении, память почемуто начинается заканчиваться на планке 1гб+200мб. Все зависит естественно от способа расходования памяти.


VD>Вот, блин, удивительно, да? Если занять 100 мег чем-то другим, то 100 мег окажется недоступным. Только причем тут фрагментация?


Фрагментируется адрессное пространство. Сборки как раз уменьшают непрерывную область. А дальше хипы LOH кладутся как бог на душу положит.

VD>Если ты даже очень постараться немерловая сборка у тебя выйдет на 100 Кб больше аналогичной на шарпе. Это 100 Кб ты в микроскоп не заметишь. У IT вырожденный случай. Вызван он убогостью шарпа и нежеланием IT переписывать этот код (так как он объемный и работает). Если бы он писал код на Немерле изначально, то его сборка была бы не больше шарповской, а меньше, так как то что он эмулирует на лямбдах и делегатах можно было бы выразить макросами генерирующими эффективный низкоуровневый код.


Макросы вдруг стали выдавать более компактный код. Похоже, тут пахнет нобелевкой

I>>У меня >50мб исходного кода. Ты хорошо понимаешь, что это значит ?


VD>Ну, и? Они превратятся в ~50 длл-и. Объем занимаемой ими памяти один хрен не будет определяться размером ДЛЛ-и, а будет определяться объемом хранимых в памяти данных.


В том числе и размером самих ДЛЛ и размером генеренного джытом кода. Когда нужно большое окно в АП, все лишние помехи это фейл.

VD>Кроме того это косвенный показатель того, что ты используешь экстенсивные методы — пишешь код руками. У нас вот код еденицами метров измеряется, но это мета-код. Он порождает уже очень много эффективного кода. Но так как мы его генерируем мы можем плевать на абстракции, инкапсуляцию и прочие заморочки нежные для рукописного кода. В итоге получается эффективный код жрущий минимум ресурсов. В ручную ты это просто задолжаться делать.


А ты похоже не читатель.

VD>Короче тратить свое время на твое образование слишком расточительно. Все равно ты не слушаешь, а долдонишь одно и то же. Оставайся дальше упертым и ищи дальше фатальные недостатки в том, чего сам понять и освоить не можешь. Твои проблемы.


Ты лучше на свое образование время потрать: "просто задай своим сборкам базовый адрес загрузки отличный от остальных. Это заметно повысит скорость загрузки, кстати."

VD>Как правильно сказал НН, если бы тебя реально заботила эффективность генерируемого немерлом кода, ты примкнул бы к нам и помог проекту. За одно свой уровень поднял бы. А у тебя другая задача — срач устроить. Но это без меня.


Давай вместе посмотрим, от кого здесь аргументы навроде "баттхёрт" и прочих вещей, включая намёки на квалификацию и тд и тд и тд ?
Re[26]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 22:06
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Факты простые — сборка и код генереный компилятором, лежат в менеджед хипах. Странно, да ?


Не странно, а полная чушь. Сборки грузятся в память как и любые другие ДЛЛ-и в Виндовс — по средствам отображаемых в память файлов. Сборки дотнета не что иное как обычный PE (Portable Executabl) файл виндовс. Возьми любую свою сборку и отправь на http://pedump.me. Сам это увидишь. За в какую область памяти грузится ДЛЛ отвечает параметр компиляции /baseaddress. Если его не задавать, то высока вероятность колизий между сборками. При этом все кроме первой сборки будут сдвигаться загрузчиком ОС. При сдвижке занимается память в процессе. Но это не менеджед-память, а обычныая (выделяемая ВиртуалАлоком). Если же задать для ДЛЛ-ей /baseaddress (можно задать в настройках проекта шарпа, например), то сборки будут проецироваться в память процесса и разделяться всеми процессами загружающими эту бсору. На объем доступного процессу адресного пространства это влиять не должно, так как не зависимо от того разделяется длл или нет они все равно занимает память.

I>Сборка, по моему, лежит в GC Heap, код — в JIT Heap.


Ранайм фрэймворка — это анменеджед код. Он не может пользоваться управляемыми хипами. Где и как лежит сборка я описал выше. Джит используют свою память, но ты можешь воспользоваться NGEN-ом. Образы полученные с помощью NGEN подгружаются в процесс точно так же как и любые другие длл-и — поецированием файлов в память.


I>Для GC, это просто хипы, как и LOH, Loader Heap, Fast, Slow, COM-Heap и тд и тд и тд.


GC вообще ничего не знает о анменеджет-хипах. Учи матчасть. Все хипы используемые дотнетом размещаются в адресном пространстве процесса и занимаются через системные функции вроде VirtualAlloc и OpenPEFile. Но это все что их обоъеденяет.

I> Он со всеми умеет работаеть, только сценарии меняются.


Ошибаешься.

I>Нет никакой особой области памяти, куда загружаются сборки. Нужна память — создаётся новый хип, если в старом память закончилась.


Ошибаешься. Хипы для этого не нужны. Точнее рантайм конечно размещает какие-то данные о типах из сборок в областях памяти отведенных под АппДомен. Но сами сборки грузятся проецированием файлов в память.

I>Сборками можно выюзать хоть всю память и при этом "Влиять на фрагментацию они не могут". Ты точно это хотел сказать ?\


Ау! Меня не слышат? Сборки, ну, кроме динамически подгружаемых, грузятся во время старта процесса. В это время для них выделяется адресное пространство. Выделяется системными (виндовыми) средствами. Далее оно не меняется. Влиять на фрагментацию LOH они не могут.

VD>>Да и смешно говорить о влиянии на фрагментацию нескольких килобайт. Ты двумя занятыми массивами фрагментируешь LOH куда больше.


I>Десятки, как минимум, мегабайт, вдруг стали килобайтами ? Ну-ну.


Какие, на фиг, десятки мегабайт? Чтобы получить сборку в десяток мегабайт нужно написать код в десятки мегабайт. Да и десятки мегабайт по сравнению с гигабйтами доступной памяти в микроскоп не различимы.

I>Фрагментируется адрессное пространство. Сборки как раз уменьшают непрерывную область. А дальше хипы LOH кладутся как бог на душу положит.


Внимание, вопрос. Если сборки грузятся практически одновременно во время загрузки приложения, то как они могу влиять на фрагментацию того, что занимается после этого?

I>Макросы вдруг стали выдавать более компактный код. Похоже, тут пахнет нобелевкой


Похоже тут пахнет невежеством.

VD>>Ну, и? Они превратятся в ~50 длл-и. Объем занимаемой ими памяти один хрен не будет определяться размером ДЛЛ-и, а будет определяться объемом хранимых в памяти данных.


I>В том числе и размером самих ДЛЛ и размером генеренного джытом кода. Когда нужно большое окно в АП, все лишние помехи это фейл.


В том числе будет 0.001%.

И вообще, если у тебя проблемы с адресным пространством в 32-битном приложении, то перейди на 64-битный процесс или, если у тебя какие-то завязки на x86, задай при старте винды ключик позволяющий отдавать под пользовательские данные 3 гига и гиг будет в твоем распоряжении.

I>Давай вместе посмотрим, от кого здесь аргументы навроде "баттхёрт" и прочих вещей, включая намёки на квалификацию и тд и тд и тд ?


Это не аргумент, а констатация факта. Чем-то тебе очень сильно задел, то ли Немерл, то ли я.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[44]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 22:14
Оценка: +1
Здравствуйте, artelk, Вы писали:

A>Да. Вызов виртуального метода (который может еще и инлайниться JITом, если фактический тип известен) заметно быстрее вызова делегата.

A>Если есть основания, что в последнем фреймворке это уже не так, просьба показать.

В последних версиях дотнета разрыв заметно сократился. Но виртуальные функции все еще быстрее.

У делегатов есть одно преимущество — они поддерживают ко[нтр]вариантность.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[46]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 22:34
Оценка:
Здравствуйте, artelk, Вы писали:

A>Это что ж получается, вызов делегата почти в 2 раза быстрее вызова виртуального метода?

A>Кто-нибудь может объяснить случившееся?

У тебя промежуточный объект да еще и через поле зацепленный. Немерловые замыкания прослоек не используют.
Вот более достоверные тесты.
Немерл:
using System;
using System.Diagnostics;

module Program
{
  Main() : void
  {
    def timer = Stopwatch.StartNew();
    mutable x = 0;
    def f = () => x ++;
    while (x < int.MaxValue)
      f();
    WriteLine(timer.Elapsed);
    _ = ReadLine();
  }
}

C#:
using System;
using System.Diagnostics;

namespace PerfTestCs2
{
  class Program
  {
    static void Main(string[] args)
    {
      var timer = Stopwatch.StartNew();
      var x = 0;
      Action f = () => x++;
      while (x < int.MaxValue)
        f();
      Console.WriteLine(timer.Elapsed);
      Console.ReadLine();
    }
  }
}

Результаты на Intel Core i7-2670QM (процессор важен, так как в Core улучшены алгоритмы предсказания ветвления):
00:00:05.7368620 - Nemerle x86 .Net 4.0
00:00:05.3505237 - Nemerle x64 .Net 4.0
00:00:06.8788378 - C#      x86 .Net 4.0
00:00:06.8795763 - C#      x64 .Net 4.0


Итого Немерл немного быстрее, но разница не столь велика. В прошлых версиях фрэймворка разница была в разы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[52]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 23:00
Оценка:
Здравствуйте, fddima, Вы писали:

F> А качество кодогенератора — да — надо улучшать. Откровенно лишние слоты в методах, излишние stloc/ldloc, когда всё должно быть совершенно просто на стёке. От этого тоже растёт объем сборки кстати,


На доли процентов.

F>и опять таки — не факт, что это JIT способен эффективно выбросить.


Факт. Выбрасывает. Иначе скорость немерловых алгоритмов была бы ниже. А она обычно даже выше получается.

F> А даже если он и может это выбросить — для JIT — это лишняя работа, а это в свою очередь тоже увеличивает startup time.


Ее опять же не видно в микроском. Если тебя трогает время джита, то используй NGEN.

А вот на замыкания время джита тратися сильно. По тому для больших немерловых сборок NGEN ощутимо ускоряет время загрузки.

F> PS: Ну, где не прав — не обезсудьте.


Тут вопрос цены и производительности. Конечно оптимизировать можно. Но и шарп не идеальный код генерирует. Ту вопрос сколько нужно вложить усилий и что получим в итоге. Мы много раз прикидывали и каждый раз забивали на оптимизации.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[46]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 23:05
Оценка:
Здравствуйте, artelk, Вы писали:

A>Это что ж получается, вызов делегата почти в 2 раза быстрее вызова виртуального метода?

A>Кто-нибудь может объяснить случившееся?

Кстати, немерловая недопотимизированность дает иногда выигрышь, как не странно. Например, в дотнете есть баг. Делегаты на статические дженерик методы инициализируются заметно дольше. Вот тест демонстрирующий это:
Немерл:
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Console;
using System.Diagnostics;
using System.Linq;

class Test
{
  public static Foo[T](x : T) : T
  {
    x
  }
}
module Program
{
  Main() : void
  {
    def timer = Stopwatch.StartNew();
    mutable x = 0;
    while (x < int.MaxValue)
    {
      def f = Test.Foo;
      x = f(x + 1);
    }
    WriteLine(timer.Elapsed);
    _ = ReadLine();
  }
}

Шарп:
using System;
using System.Diagnostics;

namespace PerfTestCs2
{
  class Test
  {
    public static T Foo<T>(T x)
    {
      return x;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var timer = Stopwatch.StartNew();
      var x = 0;
      while (x < int.MaxValue)
      {
        Func<int, int> f = Test.Foo;
        x = f(x + 1);
      }
      Console.WriteLine(timer.Elapsed);
      Console.ReadLine();
    }
  }
}

Результаты:
Nemerle: 00:00:05.3410730
C#:      00:00:22.2171454
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 23:49
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Такой уникальный подход к обсуждению проблем почему-то у проекта Немерле. Сколько ни переписывался с авторами других проектов, подход примерно такой "проблема-обсуждение" или "проблема-тикет-приоритет"


А ты попробуй высосать проблему из пальца, как в данном случае. И не забудь упомянуть про фрагментацию LOH. Это важно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[34]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.08.13 23:55
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Если для указаных проблем надо переписывать компилятор, то аргументы "присоединяйся", "сделай сам", "ждём Н2" как то неактуальны.


У твоей проблемы — небольшое превышение размеров сборок по сравнению с шарповскими в следствии того, что для функциональных объектов создаются классы переписвать весь компилятор не нужно. Но попахать нужно. И не мало. А вот бенефиты очевидны только тебе. Фрагментация LOH никого кроме тебя не волнует.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[22]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.13 00:02
Оценка:
Здравствуйте, IT, Вы писали:

IT>Если бы это сказал Влад, а не ты, то и вопросов было бы гараздо меньше. Но Влад паталогически считает все менее важные задачи абсолютно неважными и недостойными его божественного внимания


Я не понял почему ты перешел на обсуждение моей личности, но хочу напомнить, что я не являюсь владельцем проекта.

Собственно с тем, что SRE является проблемой я никогда не спорил. Если кто-то займется этой проблемой я буду только рад. У меня лично такой потребности нет. Зато есть куча более приоритетной работы. У Хардкейса, который как раз занимался переводом Немерла на бэкэнды, тоже работы выше крыши. Так что в ближайшее время он за бэкэнды вряд ли сядет.

Если кто-то хочет этой задачей заняться, мы с радостью скажем куда и как лучше копать.

В Н2 поддержка бэкэндов будет встроенной. Но до момента когда на нем можно будет с легкостью переписать немерл еще далеко. Пока что еще с парсерами не разобрались. Восстановление после ошибок оказалось более серьезным вызовом, чем мы ожидали. Пока возимся с ним.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Nemerle vs. C#. До сих пор привыкнуть не могу :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.13 00:11
Оценка:
Здравствуйте, IT, Вы писали:

IT>Вы же всё позакрывали и всех послали. Как тут можно помочь?


Не надо передергивать. Мы никого никуда не посылали. Все что я тебе сказал — ты заблуждаешся говоря о качестве кодогенерации кода для ПМ. И что проблема в другом. То что проблема есть тоже никто не спорит. Вопрос только в ее актуальности. Для всех пока что она была не актуальна.

Твой случай особый и по уму требует замены приседаний на лябдах на макросы и ДСЛ. После этого код даже уменьшится.

Рост размеров вызван генерацией классов. Решение это архитектурное и просто так от него не избавиться. Кроме того от этого и бенефиты есть.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.