![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() |
IUnknown |
![]()
Сообщение
#1
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Итак, 14 июня вышла наконец долгожданная версия GNAT GPL 2011.
Много улучшений, новая версия самой IDE (теперь это версия 5.0.1, вместо 4.3.1 из 2009-ой версии, и 4.4.1 из 2010), мне нравится больше, чем прежняя, одна возможность фильтрации результатов компиляции чего стОит (хотя это вроде было и в 2010, но мне сравнивать не с чем, я сразу перешел 2009 -> 2011, поэтому все нововведения будут относительно предпоследней версии). Что говорит официальная страничка (комментарии - мои):
Сообщение отредактировано: IUnknown - 17.06.2011 14:40 |
![]() ![]() |
TarasBer |
![]()
Сообщение
#2
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Дизассемблер работает?
Кстати, где-то был полный список новых возможностей языка на русском, я потерял. Правда JIT-компиляции там так и нет... -------------------- |
IUnknown |
![]()
Сообщение
#3
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Дизассемблер работает? Всегда работал, и в 2009 и в 2010 Pro, 2011 - в обоих версиях работает прекрасно, и в Pro и в GPL.Цитата где-то был полный список новых возможностей языка на русском, я потерял. Какое отношение JIT/AOT имеет к возможностям языка - непонятно... В лучшем случае - возможности компилятора.Правда JIT-компиляции там так и нет... |
TarasBer |
![]()
Сообщение
#4
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Всегда работал, и в 2009 и в 2010 Pro, 2011 - в обоих версиях работает прекрасно, и в Pro и в GPL.
Странно, что же у меня не то... А про стандарт есть что почитать? Спойлер (Показать/Скрыть)
-------------------- |
IUnknown |
![]()
Сообщение
#5
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Вот основное, что добавилось в Стандарт:
1. AI-0176 Quantified expressions (Показать/Скрыть)
2. AI-0128 Inequality is a primitive operation (Показать/Скрыть)
3. AI-0008 General access to constrained objects (Показать/Скрыть)
4. AI-0214 Defaulted discriminants for limited tagged (Показать/Скрыть)
5. AI-0102 Some implicit conversions are illegal (Показать/Скрыть)
6. Preconditions/Postconditions (Показать/Скрыть)
7. Conditional expressions/Case expressions (Показать/Скрыть)
8. In-out parameters for functions (Показать/Скрыть)
Насчет второй части вопроса - чуть позже... |
TarasBer |
![]()
Сообщение
#6
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
По пункту 1 - фича интересная, правда пока её применение слишком узкое. Ну вот поиск какого-нибудь ненулевого элемента в массиве с её помощью организовать можно? Чтобы она не только сообщала о наличии такого элемента, но и возвращала индекс.
По пункту 7 - как-то конструкцию обрезали, не хватает end if и end case, единообразия нету. В качестве операторных скобок сделали круглые. -------------------- |
IUnknown |
![]()
Сообщение
#7
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Ну вот поиск какого-нибудь ненулевого элемента в массиве с её помощью организовать можно? Внимательно название фичи прочел? Quantified expressions - это вообще-то кванторы. То есть, предусловие для определения упорядоченности выглядит практически так:(∀x ∈ Arr'Range) P(x) , где P - предикат "Arr(i - 1) меньше Arr(i)" Это высказывание может быть истинным или ложным. Можешь написать высказывание, которое будет определять, есть ли в массиве ненулевой элемент, и кроме этого возвращать его индекс? |
TarasBer |
![]()
Сообщение
#8
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Внимательно название фичи прочел? Quantified expressions - это вообще-то кванторы.
Ну мало ли. То есть нельзя, понятно. > Можешь написать высказывание, которое будет определять, есть ли в массиве ненулевой элемент, и кроме этого возвращать его индекс? Через костыли могу.
j: integer;
b: boolean; pragma unreferenced(b);
function Set(Index: integer) return boolean is begin
if Mas[Index].Valid then j := Index; end if;
return Mas[Index].Valid;
end;
b := for some i in Mas'Range => Set(integer(i));
Да, порядок обхода не гарантирован, но в j вернётся любой индекс нужного элемента. -------------------- |
IUnknown |
![]()
Сообщение
#9
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
https://ideone.com/xUM1j ?
Сразу скажу насчет зачем понадобилось описывать функции Plus и Mult, почему бы не сделать "+"'Access и "*"'Access - потому что prefix of "Access" attribute cannot be intrinsic. Вот такое ограничение в языке... Цитата Через костыли могу. Костыли можно чуть-чуть выпрямить: function Just_Test (arr : Vector; Index : in out Integer) return Boolean is
function Is_Valid (i : Integer) return Boolean is
begin
return b : Boolean := arr (i) /= 0 do
if b then Index := i; end if;
end return;
end Is_Valid;
begin
Index := -1;
return (for some i in arr'Range => Is_Valid (i));
end Just_Test;
|
TarasBer |
![]()
Сообщение
#10
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
По пункту 5 - то есть раньше стандарт разрешал через указатель менять константу?! Странно, что только сейчас исправили.
По поводу кода, я пытаюсь его осмыслить. Я решил поэкспериментировать, насколько большую свободу даёт эта возможность:
A,B,C: access function (L, R : Integer) return Integer;
begin
A := Second_Order (Plus'Access, Mult'Access);
B := Second_Order (Plus'Access, Div'Access);
C := Second_Order (A, B);
Ada.Text_IO.Put_Line (Integer'Image (A (2, 3)));
-- (2+3) + (2*3) = 11
Ada.Text_IO.Put_Line (Integer'Image (C (7, 5)));
-- (7+5) + (7*5) + (7+5) + (7/5) = 60
end Test;
Ограничений пока не вижу. Если так, то надо попробовать рисовалку графиков с этой фичей переписать, сравнить, насколько будет быстрее. Так вот, у меня вопрос. Что представляют собой объекты A,B,C? Простого указателя на функцию для их представления явно недостаточно, то есть в них также сидит и информация о параметрах, с которыми конструировали функцию. Каково, например, время жизни этих параметров? -------------------- |
TarasBer |
![]()
Сообщение
#11
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
В общем, решил я проверить скорость "лямбда-функций". Результаты оказались удручающие. По скорости они оказались ничуть не лучше, чем АСТ-дерево, а "байткоду", сделанному в формате массив данных вида "указатель на операцию, на левый аргумент, на правый аргумент, на результат", они сливают в два раза. Необходимость использовать в случаях, в которых важно время, такой массив очень неприятна - генерация этого массива из АСТ-дерева не так проста, как генерация лямбда-функции, а условные операторы очень геморны.
Самое плохое, на самом деле не это. Самое плохое тут то, что этот код работает только при полной оптимизации, иначе... переполнение стека (ОТКУДА): Спойлер (Показать/Скрыть)
Добавлено через 2 мин. Кстати, мне непонятно ограничение, запрещающее брать указатель от встроенных функций. Компилятор не может сам сделать то, что мы делаем руками - функцию-прокладку? -------------------- |
IUnknown |
![]()
Сообщение
#12
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Самое плохое, на самом деле не это. Самое плохое тут то, что этот код работает только при полной оптимизации, иначе... переполнение стека Самое плохое - это то, что на некоторых ОСях это вообще работает, хотя не должно. Мне, скажем, под Debian-ом, не удалось заставить твою программу работать ни при каких настройках. Вообще, в Аде очень странное понятие "замыкания", откуда все эти проблемы и происходят. Как будет побольше времени - напишу подробнее о том, что делать можно, а чего нельзя, и как поступать в том случае, когда нельзя, но очень хочется...Сообщение отредактировано: IUnknown - 26.07.2011 13:10 |
IUnknown |
![]()
Сообщение
#13
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Ну, вот такой пример отрабатывает в любом режиме, не только при полной оптимизации, надо будет только подумать, как запихать инициализацию пакета и получение из него Ret_Const в отдельную функцию:
Код (Показать/Скрыть)
Доп. пакеты прикрепил в архиве: ![]() У меня на машине в Debug-сборке способ "с лямбдой" рвёт все остальные, кроме прямого подсчета: Plain => 0.384574123 При сборке Optimize картина становится вот такой: Plain => 0.000000443 , но все равно скорость лямбд выше чем у ACT-дерева больше чем в полтора раза... Теперь еще один вопрос: ты говорил, что у тебя сборка Optimize работала. А ты проверял, оно правильно считало (я про лямбды, разумеется)? Там точно получалось 36? Вообще, очень странно, если уж работать - то должно было как раз в дебаге, оптимизированная сборка наоборот не должна была отработать... |
TarasBer |
![]()
Сообщение
#14
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> А ты проверял, оно правильно считало (я про лямбды, разумеется)? Там точно получалось 36?
Да, точно. А при отладочной сборке облом наступал при первой же попытке вычислить значение первого же Ret_Const. И я не могу точно назвать все комбинации галочек, которые дают выполняющийся код. Просто их в среде слишком много (перекинуть проект из отладочного в оптимизированный надо нажать 20 галочек на 3 вкладках, как вы работаете? Может у вас есть фирменная строка в gpr-файле, позволяющая перекидывать изменением одной директивы?). Так что можно написать баг-репорт. > package P1 is new IntPack(7); > надо будет только подумать, как запихать инициализацию пакета и получение из него Ret_Const в отдельную функцию: Я вот тоже не уверен насчёт того, что я смогу на пакетах, инициализируемых локально, создать экземпляр функции, который я смогу сохранить в глобальный объект. К тому же предполагается, что порядок действий и значение констант должны как бы вводиться пользователем, то есть порядок инициализации пакетов не должен быть мёртво вшит в код. Например, для моего варианта хоть порядок создания функций и задан руками, но я могу спокойно запихать создание функций в условный оператор, сделать массив функций итд. А массив пакетов создать я не могу. (И да, тему о всяких замыканиях, кажется, надо отделить). -------------------- |
IUnknown |
![]()
Сообщение
#15
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата К тому же предполагается, что порядок действий и значение констант должны как бы вводиться пользователем, то есть порядок инициализации пакетов не должен быть мёртво вшит в код. Например, для моего варианта хоть порядок создания функций и задан руками, но я могу спокойно запихать создание функций в условный оператор, сделать массив функций итд. В таком случае - только вот это:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
procedure Test is
type Arity is (Unary_Function, Binary_Function);
type Rec;
type Rec_Ptr is access all Rec;
type Rec (R : Arity) is limited record
Self : Rec_Ptr := Rec'Unchecked_Access;
f : access function (This : Rec_Ptr) return Integer;
case R is
when Unary_Function =>
Value : Integer;
when Binary_Function =>
Left : Rec_Ptr;
Right : Rec_Ptr;
when others =>
null;
end case;
end record;
-- Это будет та самая Ret_Const
function fun (This : Rec_Ptr) return Integer is
begin
return This.Value;
end fun;
-- А это - любая из "+", "-", "*"
generic
with function f (L, R : Integer) return Integer;
function bfun (This : Rec_Ptr) return Integer;
function bfun (This : Rec_Ptr) return Integer is
L : Rec_Ptr := This.Left;
R : Rec_Ptr := This.Right;
begin
-- Это выполняется дольше
-- return f(This.Left.f(This.Left.Self), This.Right.f(This.Right.Self));
-- Это - быстрее.
return f(L.f(L.Self), R.f(R.Self));
end bfun;
function Create_Unary(Value : Integer) return Rec_Ptr is
begin
return Result : Rec_Ptr := new Rec'(R => Unary_Function, Self => <>,
f => fun'Access, Value => Value) do
null;
end return;
end Create_Unary;
type BinFunc is access function (This : Rec_Ptr) return Integer;
function Create_Binary(bf : BinFunc;
L, R : Rec_Ptr) return Rec_Ptr is
begin
return Result : Rec_Ptr := new Rec'(R => Binary_Function, Self => <>,
f => bf, Left => L, Right => R) do
null;
end return;
end Create_Binary;
function add_bfun is new bfun(f => "+");
function sub_bfun is new bfun(f => "-");
function mul_bfun is new bfun(f => "*");
Fs : array(1 .. 17) of Rec_Ptr;
IntValue : Integer;
begin
Fs(1) := Create_Unary( 7);
Fs(2) := Create_Unary( 8);
Fs(3) := Create_Unary( 5);
Fs(4) := Create_Unary( 6);
Fs(5) := Create_Unary(48);
Fs(6) := Create_Unary( 2);
Fs(7) := Create_Unary( 3);
Fs(8) := Create_Unary( 6);
Fs(9) := Create_Unary( 9);
Fs(10) := Create_Binary(mul_bfun'Access, Fs( 3), Fs( 4));
Fs(11) := Create_Binary(mul_bfun'Access, Fs( 5), Fs( 6));
Fs(12) := Create_Binary(add_bfun'Access, Fs( 8), Fs( 9));
Fs(13) := Create_Binary(mul_bfun'Access, Fs( 7), Fs(12));
Fs(14) := Create_Binary(add_bfun'Access, Fs( 1), Fs( 2));
Fs(15) := Create_Binary(sub_bfun'Access, Fs(14), Fs(10));
Fs(16) := Create_Binary(add_bfun'Access, Fs(15), Fs(11));
Fs(17) := Create_Binary(sub_bfun'Access, Fs(16), Fs(13));
IntValue := Fs(17).f(Fs(17).Self);
Ada.Text_IO.Put_Line (Integer'Image (IntValue));
end Test;
Очень похоже на дерево, по скорости тоже почти одинаково, хотя все-таки этот способ чуть-чуть быстрее. |
![]() ![]() |
![]() |
Текстовая версия | 27.07.2025 5:27 |