Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
ASNexus
mcureenab
И где тут числа с плавающей точкой? Где тут вообще про точку написано? И при чём тут FPU? Какой FPU умеет с NUMBER работать?


А вот здесь уже Вы изволите чушь говорить - The first byte is the exponent and is followed by 1 to 20 mantissa bytes. - это по Вашему про целое число речь идет?


Ну если ты это называешь плавающей точкой, я не против.

ASNexus
А FPU (ну, например, Intel 8087 и потомки :-)) собственно для того и придуманы, чтобы работать с нецелыми числами... Надо думать, что они работают с числами не в данном формате, ну так, а куда деваться - к их рабочему формату Ораклу (а точнее тому компилятору, на котором Оракл собран) свой внутренний формат таки приходится приводить...


Очень сомневаюсь, что оракл для выполнения арифметических операций над NUMBER преобразует его в C'шный long double, тем более, что long double имеет гораздо меньшую точность, чем NUMBER. Скорее для вычислений над NUMBER используется целочисленная арифметика.
7 июн 07, 23:48    [4245363]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
zuev
если trunc() то запрос все равно сначаа поделит с максимальной точностью, а потом только применит усечение.


Попробуй хранить данные или явно преобразовывать их перед делением к типу BINARY_DOUBLE. Возможно, преобразование типов будет стоить меньше, чем непосредственно деление NUMBER с полной точностью.

Вот интересно, время деления зависит от числа значащих цифр аргументов этой операции? А от результата?
7 июн 07, 23:54    [4245369]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
ГостЪ
Guest
mcureenab
[quot zuev].
Вот интересно, время деления зависит от числа значащих цифр аргументов этой операции?

Поставь тест:)
8 июн 07, 00:21    [4245398]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
mcureenab
zuev
если trunc() то запрос все равно сначаа поделит с максимальной точностью, а потом только применит усечение.


Попробуй хранить данные или явно преобразовывать их перед делением к типу BINARY_DOUBLE. Возможно, преобразование типов будет стоить меньше, чем непосредственно деление NUMBER с полной точностью.

Вот интересно, время деления зависит от числа значащих цифр аргументов этой операции? А от результата?
Я поставил экспериментик на ХЕшке
Деление на 2 примерно в 2 раза быстрее, чем деление на 2.1
8 июн 07, 00:23    [4245402]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Elic
Member

Откуда:
Сообщений: 29979
mcureenab
Скорее для вычислений над NUMBER используется целочисленная арифметика.
Десятичная (или сторичная). В отличие от двоичной в FPU.
И вообще, целочисленность в NUMBER-арифметике - это лишь частный случай положения десятичной точки :)
8 июн 07, 10:16    [4246152]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
zuev
Member

Откуда: Кострома
Сообщений: 94
andreymx
zuev
вот у меня это деление например внутри аналит функции
avg((mm.salesum-mm.primecost)/mm.salesum) over (...)
Лично меня что-то смущает математическая сущность данного вычисления. Если я не ошибаюсь, в данном случае вы вычисляете не коэффициент по группе, а среднее коэффициентов, что чаще всего никому не нужно.


Я просто привел пример, так то у меня sum() но решил написать проще чтоб не обосновывать, так как суть не в том, что за функция, а метод ее вычисления, так как аналитическим функциям и так не легко приходится :) , так у них еще в качестве аргумента и число с лишними знаками после запятой.

хорошо, вот начеркал несколько вариантов

1.

select id,
trunc(sum(a1/a2) over (order by id))
from table


2. вроде лишняя операция, но насколько она облегчит вычисления аналитической функции, если записей много???

select id,
sum(trunc(a1/a2)) over (order by id)
from table


3.

select id,
sum(cast((a1/a2) as number) ) over (order by id)
from table


4.

select id,
(sum(a1) over (order by id)) / (sum(a2) over (order by id))
from table


только сразу предупрежу, что у меня еще в запросе пара аналит функций и полей

вот какой лучше метод (оптимальнее)?
8 июн 07, 10:21    [4246175]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Elic
Member

Откуда:
Сообщений: 29979
zuev
2. sum(trunc(a1/a2))
<> trunc(sum(a1/a2))
zuev
3. cast((a1/a2) as number)
Масло маслянное :)
zuev
4. sum(a1)/(sum(a2)
<<<<<<>>>>>> trunc(sum(a1/a2) !!!!
zuev
вот какой лучше метод (оптимальнее)?
Выбирать надо правильный
8 июн 07, 10:37    [4246281]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Elic
mcureenab
Скорее для вычислений над NUMBER используется целочисленная арифметика.
Десятичная (или сторичная). В отличие от двоичной в FPU.
И вообще, целочисленность в NUMBER-арифметике - это лишь частный случай положения десятичной точки :)


Целочисленная арифметика, в том смысле, что NUMBER дербанится на разряды, т.е. целые числа, затем над этими разрядами (в том числе и над разрядом порядка) выполняются целочисленные преобразования, такие как сложение, вычитание, умножение, деление с остатком, затем полученный результат пакуется назад в структуру NUMBER.
8 июн 07, 14:36    [4248026]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
andreymx
mcureenab
Вот интересно, время деления зависит от числа значащих цифр аргументов этой операции? А от результата?
Я поставил экспериментик на ХЕшке
Деление на 2 примерно в 2 раза быстрее, чем деление на 2.1


Долго читал, так и не понял что за экспериментик был поставлен. Ты NUMBER на NUMBER делил?
Конкретно 2 - плохой выбор, ибо для двоичной арифметики умножения и деления на степени двойки как правило реализованы аппаратно побитными сдвигами. Оптимизирующие компиляторы в этих случаях могут заменить деление или умножение на сдвиг.
2 и 2.1, например, в C++ имеют разные типы. 2 - int, 2.1 - double, тогда как 2.0 - тоже double.
8 июн 07, 14:44    [4248082]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Elic
Member

Откуда:
Сообщений: 29979
mcureenab
Целочисленная арифметика, в том смысле, что NUMBER дербанится на разряды, т.е. целые числа
В процессорной арифметике основание степени "разрядов" двойка. 2 - это целое число? (Вопрос риторический )
8 июн 07, 14:58    [4248186]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Bely
Member

Откуда: Москва
Сообщений: 1903
ГостЪ
-- тест селект с делением
  l_Statement := 'select <COLS> from test';
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(trunc(<COL>/191,3))', '+'));
  l_Time := sysdate;
Результаты:
Just select 0 seconds elapsed
"/" select 5 seconds elapsed

Ничего не буду говорить про точность измерения - просто для начала предложу измерить и другие операции:
Округление, Сложение итд.

  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'trunc(sum(<COL>/191,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(trunc(<COL>,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(<COL>/191,3)', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'trunc(sum(<COL>+191,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(<COL>+191,3)', '+'));
8 июн 07, 15:18    [4248347]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
ГостЪ
Guest
Bely

Ничего не буду говорить про точность измерения - просто для начала предложу измерить и другие операции:
Округление, Сложение итд.

  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'trunc(sum(<COL>/191,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(trunc(<COL>,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(<COL>/191,3)', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'trunc(sum(<COL>+191,3))', '+'));
  l_Statement := replace(l_Statement, '<COLS>',make_string(l_Cols, 'sum(<COL>+191,3)', '+'));


Логарифм-то позабыл! Тоже ничего не буду говорить.
8 июн 07, 15:42    [4248560]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Elic
mcureenab
Целочисленная арифметика, в том смысле, что NUMBER дербанится на разряды, т.е. целые числа
В процессорной арифметике основание степени "разрядов" двойка. 2 - это целое число? (Вопрос риторический )


Двоичная арифметика, это только модель. Так же можно утверждать, что процессор оперирует байтами (числами по основанию 256), словами и т.д. Процессор 64bit за раз может сложить 8 байт, т.е. 8 сторичных разрядов NUMBER, правда результат придётся ещё скорректировать, дабы привести его к внутреннему представлению NUMBER.
8 июн 07, 16:10    [4248790]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Elic
Member

Откуда:
Сообщений: 29979
mcureenab
Так же можно утверждать, что процессор оперирует байтами (числами по основанию 256), словами и т.д.
Нельзя. FPU даёт погрешность в последнем бите (не байте и не в слове). А number - в (пред)последней сотне.
8 июн 07, 16:23    [4248879]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Elic
mcureenab
Так же можно утверждать, что процессор оперирует байтами (числами по основанию 256), словами и т.д.
Нельзя. FPU даёт погрешность в последнем бите (не байте и не в слове). А number - в (пред)последней сотне.


Погрешность можно определять количеством точных цифр, тогда модель с 2ичной арифметикой для объяснения специфики FPU будет более продуктивна, а можно неравенством x between a-d and a+d, где a - точное значение, это несколько сложнее, но не зависит от выбранной разрядности чисел и вообще абстрагируется от природы вычислителя.
А про FPU я вообще не говорю, ибо интеловсике 80ти бытные FPU работать непосредственно с NUMBER всяко не смогут. Кроме того точность результата как для оракловой арифметики NUMBER, так и для аппаратной зависит от выполняемых функций. Всякие там log и sin возвращают меньше значащих цифр, чем + или -.
8 июн 07, 17:00    [4249145]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
ГостЪ
Guest
mcureenab
Всякие там log и sin возвращают меньше значащих цифр, чем + или -.


О сколько нам открытий чудных... :)
Я бы сказал, сколько точности вложили разработчики в расчет этих функций, столько и вернет вам цифр. И не вижу причин, почему логарифму или синусу не быть точным в пределах точности number.
8 июн 07, 17:05    [4249161]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
Elic
Member

Откуда:
Сообщений: 29979
mcureenab
точность результата для оракловой арифметики NUMBER ... зависит от выполняемых функций. Всякие там log и sin возвращают меньше значащих цифр, чем + или -.
С чего бы это им не выдерживать декларируемую number-ом точность?
8 июн 07, 17:05    [4249162]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Elic
mcureenab
точность результата для оракловой арифметики NUMBER ... зависит от выполняемых функций. Всякие там log и sin возвращают меньше значащих цифр, чем + или -.
С чего бы это им не выдерживать декларируемую number-ом точность?


Экономят наварное.

SQL> select asin(sin(0.287)) from dual;

                                  ASIN(SIN(0.287))
--------------------------------------------------
           ,28699999999999999999999999999999994129

Просто если sin вычислять через сумму в степенного ряда, то на каждой итерации накапливается погрешность в последнем разряде. Когда ряд состоит из несколько тысяч членов, то суммарная погрешность становится очень заметной. Чтобы избежать этого, нужно выполнять промежуточные вычисления с гораздо большей точностью, чем того требует результат. Например в C как правило для аргументов и результатов используют тип double, а для хранения промежуточных результатов long double, который в добавок быстрее загружается в FPU, поскольку не требует преобразования типов.
Видимо оракл решил, что такой точности вполне достаточно и применять LONG NUMBER ( ) будет непозволительной роскошью. По крайней мере для научных расчётов это так, а в финансах тригонометрию никто не использует. Когда то для расчёта процентов log использовали, но CPU проще умножать и делить в столбик.
8 июн 07, 17:21    [4249270]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
zuev
Member

Откуда: Кострома
Сообщений: 94
Вот я считаю что FPU тут вооще не причем, он считает в двоичной системе, и до его расчетов еще до кучи обработок и преобразований делает оракловый процессор.

вот можно ли его ограничить в точности, и самое то главное рационально ли это? и на каких объемах проявится? - вот мой главный вопрос.

задумался над этим с целью разгрузки сервера в первую очередь. зачем считать лишнее?
вот операцию деление с точностью неплохо было бы разработчикам внедритиь типа

x/(.2)y :)
8 июн 07, 17:57    [4249484]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
zuev
вот можно ли его ограничить в точности, и самое то главное рационально ли это?


ИМХО, нерационально, разве что задача офигенно критична по времени выполнения. Рассматривай не рафинированные примеры, а реальные задачи. Промежуточные результаты вычислений можно сохранять в БД, а не расчитывать каждый раз. Хотя ещё не известно что дороже - вычислить значение или загрузить его с диска.
8 июн 07, 18:14    [4249569]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
ГостЪ
Guest
zuev
Вот я считаю что FPU тут вооще не причем, он считает в двоичной системе, и до его расчетов еще до кучи обработок и преобразований делает оракловый процессор.

вот можно ли его ограничить в точности, и самое то главное рационально ли это? и на каких объемах проявится? - вот мой главный вопрос.

задумался над этим с целью разгрузки сервера в первую очередь. зачем считать лишнее?
вот операцию деление с точностью неплохо было бы разработчикам внедритиь типа

x/(.2)y :)


Кажется уже были намеки -
Зачем наугад оптимизировать? Надо бы оттрассировать запрос и действовать по обстановке.

P.S. в 10ке появились типы binary_float и binary_double с поддержкой fpu, если я не вру. Но сначала всё-таки надо измерить куда время уходит.
8 июн 07, 18:23    [4249605]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
ГостЪ
Guest
mcureenab


Экономят наварное.

SQL> select asin(sin(0.287)) from dual;

                                  ASIN(SIN(0.287))
--------------------------------------------------
           ,28699999999999999999999999999999994129

Просто если sin вычислять через сумму в степенного ряда, то на каждой итерации накапливается погрешность в последнем разряде. Когда ряд состоит из несколько тысяч членов, то суммарная погрешность становится очень заметной. Чтобы избежать этого, нужно выполнять промежуточные вычисления с гораздо большей точностью, чем того требует результат. Например в C как правило для аргументов и результатов используют тип double, а для хранения промежуточных результатов long double, который в добавок быстрее загружается в FPU, поскольку не требует преобразования типов.
Видимо оракл решил, что такой точности вполне достаточно и применять LONG NUMBER ( ) будет непозволительной роскошью. По крайней мере для научных расчётов это так, а в финансах тригонометрию никто не использует. Когда то для расчёта процентов log использовали, но CPU проще умножать и делить в столбик.


declare   
  A number := 0.287;
  fact number; 
  memb number;
  pw_a number;
  sinA number ;
  prev number;
  k number;
begin  
  k:=1;
  pw_a := A;
  fact := 1;
  sinA := 0;
  loop
    prev := sinA;
    memb := pw_a/fact;
    sina := sina + memb;
    k:=k+2;
    pw_a :=  a*a*pw_a;
    fact := -fact*k*(k-1);
    exit when (memb =0);
  end loop;
  DBMS_OUTPUT.PUT_LINE(k);
  DBMS_OUTPUT.PUT_LINE(to_char(sin(0.287), rpad('.', 42,'9')));
  DBMS_OUTPUT.PUT_LINE(to_char(sinA, rpad('.', 42,'9')));
end;

k=29:)
погрешность в основном образуется при возведении в степень(перемножении), а так, ты, черт возьми, прав:(
8 июн 07, 19:25    [4249811]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54381
mcureenab
andreymx
mcureenab
Вот интересно, время деления зависит от числа значащих цифр аргументов этой операции? А от результата?
Я поставил экспериментик на ХЕшке - Деление на 2 примерно в 2 раза быстрее, чем деление на 2.1
Долго читал, так и не понял что за экспериментик был поставлен. Ты NUMBER на NUMBER делил?
Конкретно 2 - плохой выбор, ибо для двоичной арифметики умножения и деления на степени двойки как правило реализованы аппаратно побитными сдвигами. Оптимизирующие компиляторы в этих случаях могут заменить деление или умножение на сдвиг.
2 и 2.1, например, в C++ имеют разные типы. 2 - int, 2.1 - double, тогда как 2.0 - тоже double.
есть у меня pivot-табличка с названием counter на 200000 строк с полем id in [1.200000]
SELECT SUM(ID/2) FROM COUNTER -- 0.125 мс
SELECT SUM(ID/3) FROM COUNTER -- 0.203 мс
SELECT SUM(ID/4) FROM COUNTER -- 0.125 мс
SELECT SUM(ID/5) FROM COUNTER -- 0.125 мс
SELECT SUM(ID/6) FROM COUNTER -- 0.203 мс
SELECT SUM(ID/2.001) FROM COUNTER -- 0.265 мс
SELECT SUM(ID/12.5) FROM COUNTER -- 0.125 мс
SELECT SUM(ID/0.000125) FROM COUNTER -- 0.125 мс
SELECT SUM(ID/0.00016) FROM COUNTER -- 0.125 мс
------------------------------------------------------------
SELECT SUM((ID+.1)/0.00016) FROM COUNTER -- 0.172 мс
SELECT SUM((ID+.1)/10.00016) FROM COUNTER -- 0.313 мс
SELECT SUM((ID+.1)/0.00025) FROM COUNTER -- 0.172 мс
SELECT SUM((ID+.1)/10.00025) FROM COUNTER -- 0.313 мс
Мне кажется, дело не в поразрядном сдвиге. Эмпирически прослеживается связь между возможность конечного деления (если такая фраза вообще применима к Number) и временем вычисления.
Но еще раз повторюсь - у меня дома XE.
8 июн 07, 20:49    [4249973]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
DimaR
Member

Откуда:
Сообщений: 1570
сравни

select avg(t) from
(select 1.0f/3.0f t from dual connect by level<=100000000);

select avg(t) from
(select 1.0/3.0 t from dual connect by level<=100000000);
9 июн 07, 12:11    [4251689]     Ответить | Цитировать Сообщить модератору
 Re: Ограничение точности во время деления, с целью уменьшить время на операцию  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
SQL> set timing on
SQL> select avg(t) from
  2  (select 1.0f/3.0f t from dual connect by level<=100000000);
(select 1.0f/3.0f t from dual connect by level<=100000000)
                         *
ERROR at line 2:
ORA-04030: out of process memory when trying to allocate 80 bytes
(kxs-heap-w,cursor work heap)


Elapsed: 00:00:26.18
SQL> 
SQL> select avg(t) from
  2  (select 1.0/3.0 t from dual connect by level<=100000000);
(select 1.0/3.0 t from dual connect by level<=100000000)
                       *
ERROR at line 2:
ORA-04030: out of process memory when trying to allocate 80 bytes
(kxs-heap-w,cursor work heap)


Elapsed: 00:00:28.89
SQL> 

Второй, как и следовало ожидать, работает дольше.
9 июн 07, 14:24    [4252358]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Oracle Ответить