1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным.
В описании темы указываем язык!!!
GNAT 2011, (с поддержкой многих фич стандарта А2012)
Итак, 14 июня вышла наконец долгожданная версия GNAT GPL 2011.
Много улучшений, новая версия самой IDE (теперь это версия 5.0.1, вместо 4.3.1 из 2009-ой версии, и 4.4.1 из 2010), мне нравится больше, чем прежняя, одна возможность фильтрации результатов компиляции чего стОит (хотя это вроде было и в 2010, но мне сравнивать не с чем, я сразу перешел 2009 -> 2011, поэтому все нововведения будут относительно предпоследней версии).
Что говорит официальная страничка (комментарии - мои):
Улучшенная поддержка А2012 (да, это - главная причина, по которой я обновился. Теперь есть возможность использовать все те фичи, которые на настоящий момент утверждены для нового стандарта, а не просто наблюдать сообщение, что это будет доступно в 2012 году, как было в прежней версии GNAT. Это и "in out" параметры для функций, и условные выражения, и Case-выражения, работают Quantified expressions, дискриминанты для лимитированных тэговых типов, Pre/Post-условия, и многое другое из того, что уже внесено в окончательную редакцию стандарта)
Улучшенные версии (GPS 5.0 - расширенная поддержка С/С++, более мощный редактор, повышенное юзабилити, GtkAda - новые виджеты, интерфейс к граф. библиотеке Cairo). (От себя добавлю, что в редакторе наконец-то сделали выпадающий список Pragma, и список атрибутов типа: )
Более гибкий и эффективный менеджер проектов
Поддержка выгрузки плагинов
Улучшенная поддержка конструкций на .NET-платформе
Более детальные сообщения об исключениях (при использовании ключа -gnateE)
полная поддержка платформы Lego Mindstorms NXT, включая аудио и I2C-сенсоры (об этом есть ролик на youtube, англ.: вот он)
Как видно, много народу хочет попробовать новую среду/новый компилятор - я скачивал пакет размером 140Мб почти 12 часов, скорость иногда падала до 2-3Кб/сек. Но сейчас с этим вроде справились.
Сообщение отредактировано: IUnknown - 17.06.2011 14:40
В общем, решил я проверить скорость "лямбда-функций". Результаты оказались удручающие. По скорости они оказались ничуть не лучше, чем АСТ-дерево, а "байткоду", сделанному в формате массив данных вида "указатель на операцию, на левый аргумент, на правый аргумент, на результат", они сливают в два раза. Необходимость использовать в случаях, в которых важно время, такой массив очень неприятна - генерация этого массива из АСТ-дерева не так проста, как генерация лямбда-функции, а условные операторы очень геморны.
Самое плохое, на самом деле не это. Самое плохое тут то, что этот код работает только при полной оптимизации, иначе... переполнение стека (ОТКУДА):
Спойлер(Показать/Скрыть)
with Ada.Text_IO; use Ada.Text_IO; with Ada.Real_Time; use Ada.Real_Time;
procedure Test is
type TCommand is record proc: access function (l,r : integer) return integer; arg1, arg2, res: access integer; end record;
function Add (l,r : integer) return integer is begin return l+r; end; function Sub (l,r : integer) return integer is begin return l-r; end; function Mul (l,r : integer) return integer is begin return l*r; end;
Commands : array (1 .. 8) of TCommand;
function Ret_Const (c: integer) return access function return integer is function Inner_Func return integer is begin return c; end; begin return Inner_Func'Unrestricted_Access; end;
function Ret_Add ( l, r: access function return integer ) return access function return integer is function Inner_Func return integer is begin return Add(l.all, r.all); end; begin return Inner_Func'Unrestricted_Access; end;
function Ret_Sub ( l, r: access function return integer ) return access function return integer is function Inner_Func return integer is begin return Sub(l.all, r.all); end; begin return Inner_Func'Unrestricted_Access; end;
function Ret_Mul ( l, r: access function return integer ) return access function return integer is function Inner_Func return integer is begin return Mul(l.all, r.all); end; begin return Inner_Func'Unrestricted_Access; end;
Funcs : array (1 .. 17) of access function return Integer;
type TNodeKind is (nkConst, nkAdd, nkSub, nkMul);
type TNode is record Kind : TNodeKind; Value : integer; L, R : access TNode; end record;
Nodes : array (1 .. 17) of aliased TNode;
function Get_Value (T: TNode) return Integer is begin case T.Kind is when nkConst => return T.Value; when nkAdd => return Add (Get_Value (T.L.all), Get_Value (T.R.all)); when nkSub => return Sub (Get_Value (T.L.all), Get_Value (T.R.all)); when nkMul => return Mul (Get_Value (T.L.all), Get_Value (T.R.all)); end case; end;
T: Time; Times: constant integer := 10_000_000;
begin -- вычисляем непосредственно -- 0.00 сек T := Clock; for j in 1 .. Times loop Data(17) := Sub ( Add (Sub (Add (7, 8), Mul (5,6)), Mul (48,2)), Mul (3, Add (6, 9))); end loop; Put_Line (Duration'Image (To_Duration (Clock - T)));
T := Clock; for j in 1 .. Times loop for i in Commands'Range loop Commands(i).res.all := Commands(i).proc(Commands(i).arg1.all, Commands(i).arg2.all); end loop; end loop; Put_Line (Duration'Image (To_Duration (Clock - T)));
T := Clock; for j in 1 .. Times loop Data(17) := Get_Value(Nodes(17)); end loop; Put_Line (Duration'Image (To_Duration (Clock - T)));
end Test;
Сверху вниз выводится время выполнения простого вычисления (я как мог старался его писать так, чтобы компилятор не сделал замену), выполнения массива указателей на процедуры, выполнения лямбда-функции, выполнения прохода по АСТ-дереву. Выводится примерно так:
Код
0.00ещё нули 1.30 2.60 2.50
Жаль, что генерация таких функций не использует подстановку в на ходу генерирующийся код, скорость бы выросла в разы. Для выполнения пользовательских скриптов это очень важно.
Добавлено через 2 мин. Кстати, мне непонятно ограничение, запрещающее брать указатель от встроенных функций. Компилятор не может сам сделать то, что мы делаем руками - функцию-прокладку?