Здравствуйте, Аноним, Вы писали:
А>Подскажите, какова разница в производительности кода Nemerle в сравнении с C#, VB и т.д?
Если сравнивать одну и ту же функциональность, то разницы нет — они все компилируются в IL. Использование списков и туплов на больших обьёмах данных может отрицательно сказываться на производительности.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: Производительность кода Nemerle
От:
Аноним
Дата:
22.02.10 16:00
Оценка:
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, Аноним, Вы писали:
А>>Подскажите, какова разница в производительности кода Nemerle в сравнении с C#, VB и т.д?
DR>Если сравнивать одну и ту же функциональность, то разницы нет — они все компилируются в IL. Использование списков и туплов на больших обьёмах данных может отрицательно сказываться на производительности.
Вопрос в какой именно IL он компилируется. Меня немного смущает реализация if, for, foreach и т.д. на макросах...
Здравствуйте, Аноним, Вы писали:
А>Вопрос в какой именно IL он компилируется. Меня немного смущает реализация if, for, foreach и т.д. на макросах...
В макросах, if действительно реализуется через match, а foreach через хвостовую рекурсию, но компилятор превращает match обратно в if, а хвостовую рекурсию в итерацию. Результат тот же, что и в C#.
А>Вопрос в какой именно IL он компилируется. Меня немного смущает реализация if, for, foreach и т.д. на макросах...
Напиши примитивную программу и посмотри, сомнения отвалятся автоматически.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Производительность кода Nemerle
От:
Аноним
Дата:
22.02.10 16:24
Оценка:
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, Аноним, Вы писали:
А>>Вопрос в какой именно IL он компилируется. Меня немного смущает реализация if, for, foreach и т.д. на макросах...
DR>В макросах, if действительно реализуется через match, а foreach через хвостовую рекурсию, но компилятор превращает match обратно в if, а хвостовую рекурсию в итерацию. Результат тот же, что и в C#.
А какой смысл в двойных преобразованиях туда-обратно?
Здравствуйте, Аноним, Вы писали:
А>А какой смысл в двойных преобразованиях туда-обратно?
Конструкции foreach/if/while/etc не являются базовыми для языка.
Базовыми являются match и лямбды, макросистема Немерла позволяет реализовать все "классические" конструкции на этих двух примитивах. Отсюда понимаем необходимость в оптимизациях анонимных функциях: инлайнинг, оптимизация хвостовых вызовов.
Здравствуйте, Don Reba, Вы писали:
DR>Если сравнивать одну и ту же функциональность, то разницы нет — они все компилируются в IL. Использование списков и туплов на больших обьёмах данных может отрицательно сказываться на производительности.
Списков — да, кортежей — нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>Вопрос в какой именно IL он компилируется. Меня немного смущает реализация if, for, foreach и т.д. на макросах...
Макросы весьма гибкая вещь, так что этого бояться не надо. А вообще, некоторые шороховатости сглаживает джит- и пре-компилятор дотнета, так что в на практике проблем с производительностью нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
DR>>Если сравнивать одну и ту же функциональность, то разницы нет — они все компилируются в IL. Использование списков и туплов на больших обьёмах данных может отрицательно сказываться на производительности.
VD>Списков — да, кортежей — нет.
Я использую Немерле для обработки графики и мой опыт показывает, что кортежы удобные, но очень дорогие, особенно с более чем тремя элементами. Простой тест:
using System.Console;
using System.Diagnostics;
module Main
{
public Main() : void
{
def n = 10_000_000;
TimeReturn(n);
TimeSet(n);
}
private TimeSet(n : int) : void
{
def watch = Stopwatch.StartNew();
mutable acc;
repeat (n)
{
mutable a, b, c, d;
Set(out a, out b, out c, out d);
acc += a; acc += b; acc += c; acc += d;
}
watch.Stop();
WriteLine($"Set: $(watch.ElapsedMilliseconds)");
}
private TimeReturn(n : int) : void
{
def watch = Stopwatch.StartNew();
mutable acc;
repeat (n)
{
def (a, b, c, d) = Return4();
acc += a; acc += b; acc += c; acc += d;
}
watch.Stop();
WriteLine($"Return: $(watch.ElapsedMilliseconds)");
}
private Set(a : out int, b : out int, c : out int, d : out int) : void
{
a = 1;
b = 2;
c = 3;
d = 4;
}
private Return4() : int * int * int * int
{
(1, 2, 3, 4);
}
}
Здравствуйте, Аноним, Вы писали:
А>Подскажите, какова разница в производительности кода Nemerle в сравнении с C#, VB и т.д?
Пока что программы написанные на Nemerle обычно бывают быстрее чем на C# или VB, потому что пока что программисты выбирающие Nemerle — это обычно уже весьма квалифицированные специалисты .
Если говорить серьезно, то производительность софта написанного на дотнет-языках больше зависит от знаний авторов кода.
Если сравнивать Nemerle с другими дотнет-языками, то в целом он порождает аналогичный код. Кое-какие проблемы могут быть вызваны связаны с особенностями реализации match. Но это касается только match-ей в которых переход происходит по большому числу литеральных значений (например, целых числе). Обычно такие match-и встречаются в сгенерированном коде вроде парсеров созданных с помощью построителей парсеров использующие конечные автоматы с большими таблицами.
Кроме того надо понимать, что функциональные абстракции не бесплатны. Замыкания создают неявно создают объекты, а вызов функции через ссылку приблизительно аналогичен виртуальному вызову. Но эти же затраты есть и в C#/VB когда используются делегаты и замыкания. Более того в Nemerle выполняются некоторые оптимизации (инлайнинг и устранение концевой рекурсии), которые делают функциональный код на Nemerle более быстрым нежели аналогиный код на C#/VB.
Макросы же не несут угрозу производительности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Don Reba, Вы писали:
DR>Я использую Немерле для обработки графики и мой опыт показывает, что кортежы удобные, но очень дорогие, особенно с более чем тремя элементами.
Кортежи 2-х и 3-х элементные — это структуры. Остальные — классы. Отсюда очевиден оверхед их использования.
В .NET 4 тоже есть кортежи, они вообще все — классы, недавно обсуждалось
Здравствуйте, hardcase, Вы писали:
H>Кортежи 2-х и 3-х элементные — это структуры. Остальные — классы. Отсюда очевиден оверхед их использования.
Правильно. Это необходимо помнить, чтобы понимать стоимость их использования и изменение семантики с value на reference при переходе на четыре элемента.
Здравствуйте, Don Reba, Вы писали:
DR>Правильно. Это необходимо помнить, чтобы понимать стоимость их использования и изменение семантики с value на reference при переходе на четыре элемента.
У меня такая философия — если элементов больше чем три, то наверно стоит задуматься об отдельном типе данных (какой-нибудь Record) для этой кухни, иначе через некоторое время будет сложно держать в голове порядок следования элементов.
А>Подскажите, какова разница в производительности кода Nemerle в сравнении с C#, VB и т.д?
По итогам реального проекта — производительность такая-же. Что в C#3 лямбды или linq, что в Nemerle лямбды (они же локальные функции) или linq — переписываются в IL сходным образом и ресурсов кушают одинаково. Любая достаточно сложная логика на match переписанная на C# будет кушать больше ресурсов — из-за того что оптимально переписать серьёзный match врукопашную — это убить того кому это потом поддерживать
У нас было требование в одной из частей проекта обеспечить время реакции в 20 ms от получения данных из сети до ответа. Уложились, причём оптимизаций связанных с тем что язык тормозил не было, оптимизировали, в основном, наши алгоритмы.
Здравствуйте, Don Reba, Вы писали:
DR>Я использую Немерле для обработки графики и мой опыт показывает, что кортежы удобные, но очень дорогие, особенно с более чем тремя элементами. Простой тест:...
Это не очень корректное сравнение.
Во-первых, кортежи более чем трех значений являются объектами (создаются в куче) и из-за этого их возврат или передача в качестве параметров медленее просто потому, что требуется создавать новый объект. Но это компенсируется тем, что в дальнейшем передается только указатель, что значительно эффективнее чем передача данных в качестве параметра. К тому же кортежи двух и трех значений используются очень часто.
Во-вторых, практически у всех типов данных есть варианты использования приводящих к большей или меньшей производительности. Вот твой пример в который добавлен еще один вариант — передача данных через поля объекта:
using System.Console;
using System.Diagnostics;
class Data
{
public mutable a : int;
public mutable b : int;
public mutable c : int;
public mutable d : int;
}
module Main
{
public Main() : void
{
def n = 10_000_000;
TimeReturn(n);
TimeSet(n);
TimeObj(n);
_ = ReadLine();
}
private TimeSet(n : int) : void
{
def watch = Stopwatch.StartNew();
mutable acc;
repeat (n)
{
mutable a, b, c, d;
Set(out a, out b, out c, out d);
acc += a; acc += b; acc += c; acc += d;
}
watch.Stop();
WriteLine($"Set: $(watch.ElapsedMilliseconds)");
}
private TimeReturn(n : int) : void
{
def watch = Stopwatch.StartNew();
mutable acc;
repeat (n)
{
def (a, b, c, d) = Return4();
acc += a; acc += b; acc += c; acc += d;
}
watch.Stop();
WriteLine($"Return: $(watch.ElapsedMilliseconds)");
}
private TimeObj(n : int) : void
{
def watch = Stopwatch.StartNew();
mutable acc;
def data = Data();
repeat (n)
{
Obj(data);
acc += data.a; acc += data.b; acc += data.c; acc += data.d;
}
watch.Stop();
WriteLine($"Obj: $(watch.ElapsedMilliseconds)");
}
private Set(a : out int, b : out int, c : out int, d : out int) : void
{
a = 1;
b = 2;
c = 3;
d = 4;
}
private Obj(obj : Data) : void
{
obj.a = 1;
obj.b = 2;
obj.c = 3;
obj.d = 4;
}
private Return4() : int * int * int * int
{
(1, 2, 3, 4);
}
}
Вариант Obj где-то вдвое быстрее нежели передача данных через out-параметры. Значит ли, что out-параметры медленны и их не стоит применять? Конечно нет! Просто для данного варианта использования передача данных через объект несколько эффективнее. Но для других случаев это будет не так.
Нужно четко понимать, что если требуется передавать множество значений, то возможно стоит воспользоваться объектами (инкапсулировать алгоритм в некотором объекте) или замыканием.
В-третьих, как и большинство тестов — этот показывает относительную разницу двух операций. Если функция не полная пустышка, а выполняет некоторые действия, то на их фоне затраты скорее всего не будет видно даже в микроскоп. Приведенный тест выполняется 10 миллионов раз, а результат — доли секунды.
В-четвертых, многое зависит от того какие данные передаются.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Производительность кода Nemerle
От:
Аноним
Дата:
23.02.10 20:41
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>Подскажите, какова разница в производительности кода Nemerle в сравнении с C#, VB и т.д?
VD>Пока что программы написанные на Nemerle обычно бывают быстрее чем на C# или VB, потому что пока что программисты выбирающие Nemerle — это обычно уже весьма квалифицированные специалисты .
VD>Если говорить серьезно, то производительность софта написанного на дотнет-языках больше зависит от знаний авторов кода.
VD>Если сравнивать Nemerle с другими дотнет-языками, то в целом он порождает аналогичный код. Кое-какие проблемы могут быть вызваны связаны с особенностями реализации match. Но это касается только match-ей в которых переход происходит по большому числу литеральных значений (например, целых числе). Обычно такие match-и встречаются в сгенерированном коде вроде парсеров созданных с помощью построителей парсеров использующие конечные автоматы с большими таблицами.
VD>Кроме того надо понимать, что функциональные абстракции не бесплатны. Замыкания создают неявно создают объекты, а вызов функции через ссылку приблизительно аналогичен виртуальному вызову. Но эти же затраты есть и в C#/VB когда используются делегаты и замыкания. Более того в Nemerle выполняются некоторые оптимизации (инлайнинг и устранение концевой рекурсии), которые делают функциональный код на Nemerle более быстрым нежели аналогиный код на C#/VB.
VD>Макросы же не несут угрозу производительности.
Написал тестовое приложение, производящее пузырьковую сортировку на C#, VB и Nemerle. В результате, на массиве из 10000 целых, код Nemerle выполнялся почти на 30% дольше чем аналог на C#.
Хотелось бы понять, я не корректно реализовал сортировку на Nemerle, или он действительно НЕ БЫСТР? Тестовый проект
Здравствуйте, Аноним, Вы писали:
А>Написал тестовое приложение, производящее пузырьковую сортировку на C#, VB и Nemerle. В результате, на массиве из 10000 целых, код Nemerle выполнялся почти на 30% дольше чем аналог на C#. А>Хотелось бы понять, я не корректно реализовал сортировку на Nemerle, или он действительно НЕ БЫСТР? А>Тестовый проект
Начать надо с того, что привести код в порядок (например для int-ов не использовать CompareTo):
public BubbleSort[T](items : array[T], left : int, right : int) : void where T : IComparable[T]
{
for (mutable i = left + 1; i <= right; i++)
for (mutable j = right; j >= i; j--)
when (items[j - 1].CompareTo(items[j]) > 0)
items[j] <-> items[j - 1];
}
public BubbleSortInt(items : array[int], left : int, right : int) : void
{
for (mutable i = left + 1; i <= right; i++)
for (mutable j = right; j >= i; j--)
when (items[j - 1] > (items[j]))
items[j] <-> items[j - 1];
}
Ответ дает рефлектор:
public static void BubbleSortInt(int[] items, int left, int right)
{
int index = 0;
int num2 = 0;
for (num2 = left + 1; ((num2 <= right) ? 1 : 0) != 0; num2++)
{
index = right;
while (true)
{
if (((index >= num2) ? 1 : 0) == 0)
{
break;
}
if (((items[index - 1] > items[index]) ? 1 : 0) != 0)
{
int num3 = index - 1;
int num4 = items[index];
items[index] = items[num3];
items[num3] = num4;
}
index--;
}
}
}
Видна ненужная проверка с тернарным оператором. Впрочем, даже с таким тормозом производительность практически эквивалентна VB.NET. По хорошему стоит посмотреть на Mono, а также попробовать скомпилировать примеры вручную, но щас уже поздно совсем.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Производительность кода Nemerle
От:
Аноним
Дата:
24.02.10 06:54
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Написал тестовое приложение, производящее пузырьковую сортировку на C#, VB и Nemerle. В результате, на массиве из 10000 целых, код Nemerle выполнялся почти на 30% дольше чем аналог на C#. А>>Хотелось бы понять, я не корректно реализовал сортировку на Nemerle, или он действительно НЕ БЫСТР? А>>Тестовый проект
H>Начать надо с того, что привести код в порядок (например для int-ов не использовать CompareTo): H>
H>public BubbleSort[T](items : array[T], left : int, right : int) : void where T : IComparable[T]
H>{
H> for (mutable i = left + 1; i <= right; i++)
H> for (mutable j = right; j >= i; j--)
H> when (items[j - 1].CompareTo(items[j]) > 0)
H> items[j] <-> items[j - 1];
H>}
H>public BubbleSortInt(items : array[int], left : int, right : int) : void
H>{
H> for (mutable i = left + 1; i <= right; i++)
H> for (mutable j = right; j >= i; j--)
H> when (items[j - 1] > (items[j]))
H> items[j] <-> items[j - 1];
H>}
H>
H>Ответ дает рефлектор: H>
H>public static void BubbleSortInt(int[] items, int left, int right)
H>{
H> int index = 0;
H> int num2 = 0;
H> for (num2 = left + 1; ((num2 <= right) ? 1 : 0) != 0; num2++)
H> {
H> index = right;
H> while (true)
H> {
H> if (((index >= num2) ? 1 : 0) == 0)
H> {
H> break;
H> }
H> if (((items[index - 1] > items[index]) ? 1 : 0) != 0)
H> {
H> int num3 = index - 1;
H> int num4 = items[index];
H> items[index] = items[num3];
H> items[num3] = num4;
H> }
H> index--;
H> }
H> }
H>}
H>
H>Видна ненужная проверка с тернарным оператором. Впрочем, даже с таким тормозом производительность практически эквивалентна VB.NET. По хорошему стоит посмотреть на Mono, а также попробовать скомпилировать примеры вручную, но щас уже поздно совсем.
Не совсем понял, как Mono или ручная компиляция может повлиять на результаты теста?
Здравствуйте, Аноним, Вы писали:
А>Написал тестовое приложение, производящее пузырьковую сортировку на C#, VB и Nemerle. В результате, на массиве из 10000 целых, код Nemerle выполнялся почти на 30% дольше чем аналог на C#. А>Хотелось бы понять, я не корректно реализовал сортировку на Nemerle, или он действительно НЕ БЫСТР? А>Тестовый проект
А -optimize ты добавлял при компиляции? Компилировать нужно в релиз добавляя -optimize, а запускать из консоли.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>А -optimize ты добавлял при компиляции? Компилировать нужно в релиз добавляя -optimize, а запускать из консоли.
Собственно приведенный мною листинг рефлектора и есть продукт компиляции в Release-конфигурацию.
Сегодня пробовал собирать руками с явной -O опцией. Та же история.
Здравствуйте, hardcase, Вы писали:
H>Собственно приведенный мною листинг рефлектора и есть продукт компиляции в Release-конфигурацию. H>Сегодня пробовал собирать руками с явной -O опцией. Та же история.
Ну, перепишете этот код с использованием рекурсивных фукнций (только короче выйдет) или поправьте этот for. Его явно на скорую руку кто-то слепил и оставил как есть, так как он по жизни на фиг не уперся.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>Написал тестовое приложение, производящее пузырьковую сортировку на C#, VB и Nemerle. В результате, на массиве из 10000 целых, код Nemerle выполнялся почти на 30% дольше чем аналог на C#. А>Хотелось бы понять, я не корректно реализовал сортировку на Nemerle, или он действительно НЕ БЫСТР? А>Тестовый проект
Я там (в ревизии 8631) кое что подкрутил в кодогенерации. Попробуйте еще разок свои тесты прогнать (с новой версией).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Я там (в ревизии 8631) кое что подкрутил в кодогенерации. Попробуйте еще разок свои тесты прогнать (с новой версией).
Пришлось подправить пару копипаст багов в тестах Анонимуса.
Теперь рефлектор не показывает никаких тернарных операций в немерловых операторах сравнения:
public static void BubbleSortInt(int[] items, int left, int right)
{
int index = 0;
int num2 = 0;
for (num2 = left + 1; num2 <= right; num2++)
{
index = right;
while (true)
{
if (index < num2)
{
break;
}
if (items[index - 1] > items[index])
{
int num3 = index - 1;
int num4 = items[num3];
items[num3] = items[index];
items[index] = num4;
}
index--;
}
}
}
Странно, а ведь проверял — что-то я похоже намудрил, и Ctrl+F5 это не также как запуск с "консоли".
Действительно, Nemerle пока еще проигрывает даже если добавить блок unchecked (если в опциях компиляции VB.NET проекта убрать проверку переполнения, то его результат идентичен с C#).
А>версия самая последняя(взял инсталлер с google nemerle), nemerle проект компилит не подецки долго, что есть не оч хорошо
Эта проблема видимо только в x64 системах: одна и та же ревизия компилятора на Win 2003 R2 Sp2 работает влет, а вот на XP x64 Sp2 — невероятно медленно.
Здравствуйте, hardcase, Вы писали:
H>Теперь рефлектор не показывает никаких тернарных операций в немерловых операторах сравнения:
Это я и подкручивал. Ребята разрабатывавшие MSIL были или очень веселыми ребятами, или ленивыми ассемблерщиками. Они ввели весьма странный набор команд который требует трех инструкций для реализации => <= или требует переписывания логики булевых выражений (что не так то просто). При этом они тупо оптимизировали (в JIT-компиляторе и NGen) генерацию маш.кода для составных инструкций.
Те кто писал кодогенерацию для немерла выбрали другой путь реализации операторов сравнения (>, <, => и <=) которые JIT не оптимизирует (а зря, кстати). Я переписал все образом сходным с тем как это происходит в C#. Потому и Рефлектор стал распознавать паттерн корректно.
Еще не мешало бы подправить макрос "for", так чтобы он генерировал код полностью аналогичный for-у из C#. Но мне этим заниматься в лом, так как сам я "for" почти не использую, и есть у нас и другие дела (с). Если ктому-то охота потренироваться с не сложным макросом, то — милости просим. Присылайте код сюда, или комитьте его в СВН (если есть права). Но после тестов (в том числе и в рефлекторе).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>nemerle проект компилит не подецки долго, что есть не оч хорошо
Видимо что-то не так с прекомпиляции NGen-ом. Если можете, попробуйте сами, вручную, прекомпилировать все бинарники из каталога %ProgramFiles%\Nemerle с помощью ngen.exe.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hardcase, Вы писали:
H>Эта проблема видимо только в x64 системах: одна и та же ревизия компилятора на Win 2003 R2 Sp2 работает влет, а вот на XP x64 Sp2 — невероятно медленно.
Есть два различия:
1. Макрос "for" реализован не очень качественно.
2. Немерле генерируется опрераторы сравнения с логикой обратной C#.
Еще может быть, что некорректно реализован unchecked.
Если у кого-то есть время, сравните IL.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, hardcase, Вы писали:
H>>Эта проблема видимо только в x64 системах: одна и та же ревизия компилятора на Win 2003 R2 Sp2 работает влет, а вот на XP x64 Sp2 — невероятно медленно.
VD>Есть два различия: VD>1. Макрос "for" реализован не очень качественно. VD>2. Немерле генерируется опрераторы сравнения с логикой обратной C#.
Это я про запуск и работу компилятора.
При этом эффективность кода в этих пузырьковых бенчмарках идентична (на глаз не заметна) и архитектура не влияет. Те результаты, которые я выкладывал — чушь.
Здравствуйте, hardcase, Вы писали:
H>При этом эффективность кода в этих пузырьковых бенчмарках идентична (на глаз не заметна) и архитектура не влияет. Те результаты, которые я выкладывал — чушь.
Согласен, но проще устранить всяческие причины для придирок, чем объяснять все это тем кто пытается найти фатальный недостаток.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Поломав голову над for я так и не сообразил, как можно сохранить структурную семантику C#-овского цикла for() в Nemerle.
В C# конструкция (a — это List<string>):
for(int i = 0; i < a.Count; ++i)
System.Console.WriteLine(a[i]);
что совершенно эквивалентно записи
int i = 0;
goto check;
loop:
System.Console.WriteLine(a[i]);
++i;
check:
if(i < a.Count) goto loop;
В Nemerle для аналогичного for() получаем хвостовую рекурсию
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, hardcase, Вы писали:
H>>Не понятно, почему такой while-цикл работает медленнее for...
VD>Не факт, что дело в реализации for.
VD>Может быть все же проблема в том, что не кооректно работает unchecked?
Разобрался. unchecked в Nemerle работает нормально, дело не в нем.
Оказывается следующий код обмена значениями (именно такой получается для оператора <->) в тестах
int prev = index - 1;
int x = items[prev];
items[prev] = items[index];
items[index] = x;
работает ровно в два раза медленнее
int x = items[index - 1];
items[index - 1] = items[index];
items[index] = x;
Т.о. если заменить оператор обмена значениями <-> на второй вариант (как в C#) все тесты отрабатывают за одинаковое время.
Хоть структурная реализация for в Nemerle и отличается от C#, но она ей эквивалентна по скоростным параметрам (в приведенном тесте, на самом деле чуточку медленнее).
Все встало на свои места.
Почти уверен, что в иной ситуации все может оказаться наоборт, так как переменную куда проще разместить в регистре нежели производить оптимизацию "устранение общего подвыражения".
Во истину — не исповедимы пути Майкрософта.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Производительность кода Nemerle
От:
Аноним
Дата:
21.03.10 10:43
Оценка:
H>Разобрался. unchecked в Nemerle работает нормально, дело не в нем.
H>Оказывается следующий код обмена значениями (именно такой получается для оператора <->) в тестах H>
H>int prev = index - 1;
H>int x = items[prev];
H>items[prev] = items[index];
H>items[index] = x;
H>
H>Т.о. если заменить оператор обмена значениями <-> на второй вариант (как в C#) все тесты отрабатывают за одинаковое время. H>Хоть структурная реализация for в Nemerle и отличается от C#, но она ей эквивалентна по скоростным параметрам (в приведенном тесте, на самом деле чуточку медленнее). H>Все встало на свои места.
Закомментитровал код обмена значений и получил такой-же результат, что и ранее. Оператор <-> сдесь не причем.
Здравствуйте, Аноним, Вы писали:
А>Закомментитровал код обмена значений и получил такой-же результат, что и ранее. Оператор <-> сдесь не причем.
Вот проект.
Там также есть проект для Boo (я пользовался #develop) он значительно медленее работает, но это из-за кое каких своих заморочек с массивами в Boo.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[17]: Производительность кода Nemerle
От:
Аноним
Дата:
21.03.10 18:22
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Закомментитровал код обмена значений и получил такой-же результат, что и ранее. Оператор <-> сдесь не причем.
H>Вот проект. H>Там также есть проект для Boo (я пользовался #develop) он значительно медленее работает, но это из-за кое каких своих заморочек с массивами в Boo.
В моей версии проекта не было unchecked! Задействовав его, получил идентичные результаты у Nemerle и С#!
В проектах C#, по-умолчанию, не используется проверка переполнения, а в Nemerle похоже наоборот!
Это и приводит к таким "печальным" результатам. К стати, у проекта Nemerle, в его свойствах
проверка переполнения не настраивается?! Оператор <-> ни какого влияния на результаты теста не оказывает.
Здравствуйте, Аноним, Вы писали:
А>В проектах C#, по-умолчанию, не используется проверка переполнения, а в Nemerle похоже наоборот! А>Это и приводит к таким "печальным" результатам.
Откровенно говоря непойму что печельного в результатах. Разницу не заметиль в микроскоп. При этом постоянно ведется контроль переполнения. Ну, а там где нужно выжать максимум скорости не сложно и unchecked воспользоваться.
А>К стати, у проекта Nemerle, в его свойствах проверка переполнения не настраивается?!
Нет. Хотя можно было бы и добавить. Создай фича-реквест в багтрекере.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, Аноним, Вы писали:
А>>>Закомментитровал код обмена значений и получил такой-же результат, что и ранее. Оператор <-> сдесь не причем.
H>>Вот проект. H>>Там также есть проект для Boo (я пользовался #develop) он значительно медленее работает, но это из-за кое каких своих заморочек с массивами в Boo.
А>В моей версии проекта не было unchecked! Задействовав его, получил идентичные результаты у Nemerle и С#! А>В проектах C#, по-умолчанию, не используется проверка переполнения, а в Nemerle похоже наоборот!
Вообще стоит добавить такую настройку. В принципе могу сделать это.
А>Это и приводит к таким "печальным" результатам. К стати, у проекта Nemerle, в его свойствах А>проверка переполнения не настраивается?! Оператор <-> ни какого влияния на результаты теста не оказывает.
На моей системе влияет. Аккуратно в 2 раза медленнее.
Здравствуйте, hardcase, Вы писали:
H>В Nemerle для аналогичного for() получаем хвостовую рекурсию
... H>Которая по генерируемому коду эквивалентна while() циклу C#:
... H>Не понятно, почему такой while-цикл работает медленнее for...
Здравствуйте, seregaa, Вы писали:
S>На c# while тоже работает медленнее, чем for?
Вроде же как разобрались — цикл на скорость почти не влиял.
И вообще, проблема устранена. Так что шарп, васик и немерл работают одинаково быстро (или медленно, если вы пессимист ).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Вроде же как разобрались — цикл на скорость почти не влиял. VD>И вообще, проблема устранена. Так что шарп, васик и немерл работают одинаково быстро (или медленно, если вы пессимист ).
Ага, не дочитал до unchecked. Ну тады ok )