LINUX.ORG.RU
 

DMD 2.020 и DMD 1.036


0

0

20 октября вышла новая версия компилятора DMD. Наряду с традиционным большим количеством багфиксов есть несколько значительных изменений:

  • В обоих ветках улучшена производительность ассоциативных массивов.
  • Разрешён возврат значений из функций по не-константной ссылке. (Ранее был запрещён вообще)
  • Стандартная библиотека Phobos была отделена от рантайма. Появилась возможность нормально использовать Phobos и Tango в одной программе. Точнее, появится с предстоящим релизом Tango.
Автор предупреждает, что в этом релизе произошло большое количество изменений в коде и вероятно появление ошибок.

>>> Changelog D2

>>> Changelog D1

>>> Подробности


[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:25:30  

Re: DMD 2.020 и DMD 1.036

> да

0_o Они написали ещё один компилятор Java?

/me ушёл читать исходники

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 10:25:45  
r

Re: DMD 2.020 и DMD 1.036

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

ну - может тогда слово inline не такая плохая вещь коль это конкурент плюсам? Просто вместо основного хостязыка передаваь строки которые разберуться пусть даже шаблонами. То есть я так понимаю аналогичный ход с нешаблонами не работает, а глядя на реализацию этого редьюса или подобного лично я наблюдаю страшную логику по разбору дочернего языка вместо простой и понятной реализации функциии на хост языке.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 10:23:15  
r

Re: DMD 2.020 и DMD 1.036

>Кажись где-то ошибка. Либо Collections<Integer>.reduce либо Collections.reduce<Integer>. Или я что-то путаю?

Все правильно. Параметризованный метод.

ident.<Param>method()

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 15:28:33  
r

Re: DMD 2.020 и DMD 1.036

>0_o Они написали ещё один компилятор Java?

Типа того. Но не совсем любой - это как бы expression language для динамического скриптинга. то есть класс задекларировать там нельзя.

***** ()
[#] Ответ на: от  
r

Re: DMD 2.020 и DMD 1.036

>Прошу уточнить пример.

Пример точный и работающий - методом cut'n'paste.

Просто он заделан на моих либах их проекта - еслои хошь в воскресенье (делаю ноги на пару дней) запосчу его раелизованного на публичнодоступных либах вместе с реализацией и ссылками на составляющие, чтоб каждый мог попробовать.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:36:30  
r

Re: DMD 2.020 и DMD 1.036

Могу даже 2 версии - с BGGA и с JEXL.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:36:30  

Re: DMD 2.020 и DMD 1.036

Опенсурс будет благодарен. :D

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 15:38:53  
r

Re: DMD 2.020 и DMD 1.036

ну ok, в воскресенье будет.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:31:00  

Re: DMD 2.020 и DMD 1.036

> лично я наблюдаю страшную логику по разбору дочернего языка

Эм... Где? В std.algorithm.reduce никакого разбора языка нет. Простое и понятное описание действий. Обьявляется NXhelper, применяющий одну функцию для одного массива, проводятся пара тестов на валидность входных данных, определяется возвращаемый тип и применяется NXhelper к каждой паре массив-функция.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 15:44:43  
r

Re: DMD 2.020 и DMD 1.036

А это я перепутал с binaryFun. Страшный код - там:

typeof({
static ElementType1 a;
static ElementType2 b;
return mixin(comp);
}())
binaryFun(ElementType1, ElementType2)(ElementType1 a, ElementType2 b)
{
return mixin(comp);
}


То есть не то чтобы совсем страшный - но что-то неправильное есть в подобном описании "простых сортировок".

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:31:00  

Re: DMD 2.020 и DMD 1.036

> То есть я так понимаю аналогичный ход с нешаблонами не работает

Данный reduce позволяет бОльшую часть работы выполнить при компиляции. Конечно можно все типы заменить на Object, и сделать разбор выражений в рантайме или передачу делегата. Тогда получится те самые JEXL и BGGA соответственно, которые имеем в Java.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 15:56:12  

Re: DMD 2.020 и DMD 1.036

binaryFun - это просто функция от двух аргументов, которую можно задать и строкой и делегатом.
А реализация у него такая страшная из-за бага в компиляторе №1816. Там же всё написано.

typeof(mixin(comp)) binaryFun(ElementType1, ElementType2)(ElementType1 a, ElementType2 b)
{
    return mixin(comp);
}

Так будет выглядеть код после фикса бага №1816.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 16:09:52  
r

Re: DMD 2.020 и DMD 1.036

вот реализация на скале:

def reduce[T]( f: (T,T) => T*)( seeds: T* )(l: T*) = {
    val r = Array.concat(seeds);
    for(e <- l; i <- 0 until r.length ) r(i) = f(i)(r(i), e);
    r
}

reduce[Int]((x,y) => x + y, (x,y) => x * y)(0, 1)( 1,2,3,4,5 )

res17: Array[Int] = Array(15, 120)

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 16:40:05  
r

Re: DMD 2.020 и DMD 1.036

это я к тому что там нефиг делать на этапе компиляции

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 16:09:52  
r

Re: DMD 2.020 и DMD 1.036

К стати какое значение имеют множественные скбоки - только группировочное?
В скале (как и прочих FPL) например можно получить частично параметризованную функцию:

scala> def rsum = = reduce[Int]((x,y) => x + y)(0) _

scala> rsum(1,2,3,4,5)
res23: Array[Int] = Array(15)

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 16:40:05  

Re: DMD 2.020 и DMD 1.036

Со строками использование короче получается почти на десять символов ;)

reduce[Int]((x,y) => x + y, (x,y) => x * y)(0, 1)( 1,2,3,4,5 )
reduce!("a + b", "a * b")(0, 1, [1, 2, 3, 4, 5]);

А вот несколько списков аргументов в scala - это удобно.

Интересно будет сравнить производительность на scala, на D с делегатами и на D со строками.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 17:04:17  

Re: DMD 2.020 и DMD 1.036

> какое значение имеют множественные скбоки - только группировочное?

Первые скобки - список параметров шаблона, вторые - список параметров функции. По шаблонным параметрам вроде можно частично параметризовать.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 16:40:05  

Re: DMD 2.020 и DMD 1.036

T[] reduce(T)( T delegate (T, T)[] f,  T[] seeds, T[] l) {
    auto r = seeds.dup;
    foreach (i; 0 .. r.length) {
        foreach (e; l) {
            r[i] = f[i](r[i], e); 
        }   
    }   
    return r;
}
void main() {
    auto array = [1, 2, 3, 4, 5];
    alias typeof(array[0]) T;

    auto r = reduce([(T a, T b) { return a + b; }, (T a, T b) { return a * b; }], [0, 1], [1, 2, 3, 4, 5]);
    writefln(r[0]);
    writefln(r[1]);

    auto rsum = (T[] a) { return reduce( [(int a, int b) { return a + b;}], [0], a); };
    writefln(rsum([1, 2, 3, 4, 5]));
}

Выводит:
15
120
[15]

Конечно, использованный метод "частичной параметризации" можно назвать грязным хаком, но я сомневаюсь, что
в scala на самом деле происходит что-то другое. scala безоговорочно выигрывает только в синтаксисе замыканий, и
наличии средства для группировки аргументов. В D приходится использовать массивы.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 16:56:43  

Re: DMD 2.020 и DMD 1.036

> это я к тому что там нефиг делать на этапе компиляции

Как минимум проверять соответствие количества seeds количеству функций лучше при компиляции. Но реализация Александреску позволяет, кроме того, передавать строки вместо делегатов. Вдруг кому-то так больше нравится?

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 17:14:52  

Re: DMD 2.020 и DMD 1.036

> По шаблонным параметрам вроде можно частично параметризовать.

Нет, нельзя. :(

Разве что для template foo(T1, T2, T3) {...}

Сделать так: template fooif(T) { mixin foo!(int, float, T); }

Впрочем, результат полностью соответствует ожидаемому для любого шаблона foo.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 17:48:40  

Re: DMD 2.020 и DMD 1.036

Надо будет попробовать уломать WB на возврат последнего вычисленного значения из функции... Повсеместные return'ы глаз режут.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 17:51:04  
r

Re: DMD 2.020 и DMD 1.036

>Как минимум проверять соответствие количества seeds количеству функций лучше при компиляции.

Это в общем случае невозможно.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 17:48:40  
r

Re: DMD 2.020 и DMD 1.036

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

Это не совсем средство группировки - это оптимизированный синтаксис для функции возвращающей функции возвращающей функции..... такой себе карринг- только работу по разбору взял на себя компилятор. Потому частичная параметризация так легко делается. Тип reduce:

[T]((T, T) => T*) => (T*) => (T*) => Array[T]

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 18:15:46  

Re: DMD 2.020 и DMD 1.036

> Надо будет попробовать уломать WB на возврат последнего вычисленного значения из функции...

А разве еще есть время? D 2.0 планировался осенью.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 17:06:57  

Re: DMD 2.020 и DMD 1.036

scala - решение r, приведённое выше.
D делегаты - моё решение, приведённое выше.
D шаблоны - решение Александреску из std.algorithm.

Время компиляции:
scala - 2.71 (fsc неосилил)
D делегаты - 0.09
D шаблоны - 0.12

Время работы для 1.000.000 операций reduce:
scala - 3.36 из них стартап - всего 0.13
D делегаты - 1.02
D шаблоны - 0.03

То же, но с распечаткой каждого значения в /dev/null
scala - 6.46
D делегаты - 1.55
D шаблоны - 0.52

Для D в обоих случаях прибавка ко времени была одинакова, следовательно весь цикл не был "соптимизирован в /dev/null" ни в том ни в другом случае.

Все промежутки - в секундах. Каждый тест проводился 5 раз, приведён лучший результат. программа на scala скомпилена scalac и запущена на sun-jdk-1.6.0.07. D - DMD 2.020. Флаги оптимизации не установлены. (При установке флагов -inline -O D на шаблонах с распечаткой отрабатыает за 0.32)

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 31.10.2008 18:48:15  

Re: DMD 2.020 и DMD 1.036

При частичной параметризации время работы программы на scala изменяется в пределах 0.05с в разные стороны для тестов с выводом и без. Значит ли это, что группировка аргументов - не более чем syntactic sugar, или просто пример неудачный?

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 19:19:47  

Re: DMD 2.020 и DMD 1.036

Скале оптимизация помогла сбросить пол секунды в тесте с выводом. Время прохождения теста без вывода - не изменилось. Время компиляции увеличилось в полтора раза.

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 31.10.2008 19:30:27  
r

Re: DMD 2.020 и DMD 1.036

>Значит ли это, что группировка аргументов - не более чем syntactic sugar, или просто пример неудачный?

Ну - это синтаксическия сахар вокруг функций возвращающей функцию возвращающей функцию. Там унутри получается грубо говоря 3 аппликации - в D - одна.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 05.11.2008 19:04:18  
r

Re: DMD 2.020 и DMD 1.036

К стати этот reduce можно в скале еще по другому вывать:

reduce[Int]((_+_),(_*_))(0,1)(1,2,3,4,5)

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 09.11.2008 2:00:00  

Re: DMD 2.020 и DMD 1.036

Впрочем функциональную парадигму и не пытаются причислить к поддерживаемым D.

Результаты теста производительности лучше прокомментируй. Не может Scala в 200 раз медленнее быть. На http://shootout.alioth.debian.org ни по одному тесту нет таких разгромных результатов. Что я сделал не так?

*** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от naryl 09.11.2008 5:31:10  
r

Re: DMD 2.020 и DMD 1.036

>Что я сделал не так?

Принципиальная разница в реализации. Функция на D в результате компиляции - это просто одна функция. Да еще учитывая инлайнинги. В скале в данном случае:

1. Все есть first class object включая функции.
2. Сам тип это функция возвращающая функцию врзвращающая функцию.

То есть фактически в каждом цикле инстанции руется три объекта для самого определения редьюса, плюс два объекта для лямбд, плюс обекты для списков - короче в каждом цикле чуть больше чем дохрена сложнее работа происходит.

Если убрать тайп параметр - то быстрее на 25% (за счет отсутствия кучи боксингов в примитивы - операции над примитивными типами в jvm если надо производительность лучше в общем виде не решать с другими типами - будет нагенерено много боксинга. К стати повторное исполнение цикла дает ускорение ~10% за счет джита (на этом коде - более простой у меня ускорился в 3 раза). А если делать не миллион редьюсов, а редьюс миллиона - быстрее на порядок - у меня прыгает с ~3 секунд до ~0.3 секунд - то есть действительно плодиться много объектов. В данном случае речнь не в жаве а в том что все first class object, а поскольку жвм не понимает, что обектами бывает что-то отличное от класса - то Мартину и ребятам пришлось все компилять в классы и как следствие инстанциируется дохрена объектов.

***** ()
[#] Ответ на: Re: DMD 2.020 и DMD 1.036 от r 09.11.2008 6:43:13  

Re: DMD 2.020 и DMD 1.036

Может кто-нибудь scala, если это возможно, под другими vm тестировал?

> а редьюс миллиона - быстрее на порядок


Я делал именно миллион редьюсов. Кстати, дизассемблер показывает, что в результате разворачивания шаблонной реализации Александреску (со строкой) получается цикл с одним call по статическому адресу.

*** ()