Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 4698
Рейтинг: 426
#16: 2014-06-10 17:37:47 ЛС | профиль | цитата
Galkov писал(а):
Информация к размышлению: быстродействие элемента состоит из двух (грубо говоря) частей: из "стрельбы" по интерфейсным точкам, и собственно вычислительного процесса.
Ну если второй гораздо больше - тогда ДА. Результатами сразу можно хвастаться.

Во-первых, здесь как раз вариант "второй гораздо больше". Во-вторых, "стрельба" по точкам одинаковая для каждого тестируемого, следовательно, можно просто один раз ее вычислить и вычесть (результат от этого не сильно изменится, как была разница в разы, так и останется).
Galkov писал(а):
Добавить к нему вычисление константных выражений в Compile-Time

Это тогда надо строить дерево выражения, как я понимаю. Если подскажешь метод, как обойтись без него и не переделывать парсер снова, то можно добавить.
А вообще если подумать, а надо оно в MathParse? Как никак FastMathParse никуда не девается, и для особо критичных вычислений остается он.
карма: 10
0
Разработчик
Ответов: 26113
Рейтинг: 2126
#17: 2014-06-11 11:53:55 ЛС | профиль | цитата
Galkov писал(а):
Пока мне некогда, но я обязательно поучаствую

Ждемс
карма: 22

0
Ответов: 9906
Рейтинг: 351
#18: 2014-06-11 13:13:44 ЛС | профиль | цитата
Будем считать, что все смекнули, что это из меня цитата
Прикольный форум...
карма: 9

0
Разработчик
Ответов: 26113
Рейтинг: 2126
#19: 2014-06-11 14:39:31 ЛС | профиль | цитата
Galkov писал(а):
что все смекнули, что это из меня цитата

Ой! Точно Исправил
карма: 22

0
Разработчик
Ответов: 4698
Рейтинг: 426
#20: 2014-06-13 22:11:53 ЛС | профиль | цитата
Обновлен компонент до версии 1.2:

  • Исправлен баг с неверной компиляцией выражения, использующего пользовательские функции (например %1(...), myfunc(...))
  • Добавлено событие onDebugText. На данный момент при DebugMode = True выводит в нее "исходный" код скомпилированного выражения. (в кавычках потому, что исходного кода как бы и нету ).
Ссылка в первом посте.
карма: 10
0
Ответов: 9906
Рейтинг: 351
#21: 2014-06-17 14:21:32 ЛС | профиль | цитата
Assasin писал(а):
Во-первых, здесь как раз вариант "второй гораздо больше". Во-вторых, "стрельба" по точкам одинаковая для каждого тестируемого, следовательно, можно просто один раз ее вычислить и вычесть (результат от этого не сильно изменится, как была разница в разы, так и останется)

Двойка, Вам, товарищ студент

Во-первых: Ваше утверждение ничем не подтверждено. А мои измерения говорят о том, что оно не очень соответствует действительности. Мягко говоря.

Во-вторых: "можно вычесть", и реально вычесть - есть разные вещи. Хотя бы потому, что перед тем, как "вычесть" - надо измерить вычитаемое. Внимание: сначала измерить, а уже потом уже говорить про "кто-кого гораздо больше".

В третьих: "Разы" ли это, и сколько этих "разов" - вопрос интересный. И какие "разы" нас интересуют. Меня лично интересуют "разы для собственного времени". Не потому, что "интерфейсное время" меня устраивает, а потому, что в рамках работы над элементом, второе - это форсмажор (если по-русски - то хучь в ухо мочись), а первое как раз и определяет качество моей (твоей, его, и т.п.) работы.

Зная соотношение этих времен, можно рассуждать о необходимости (или - нет) его улучшения.
НО, обратите внимание -- ЗНАЯ. А не просто языком почесавши

Вот, смотрите код. ЭКСПЕРИМЕНТ делается примерно так:
Add(MainForm,2953706,42,42)
{
Width=361
Height=228
Position=1
}
Add(MathParseEx,204878,385,133)
{
MathStr="(%1+%2)"
Point(onError)
link(X1,13913289:Var3,[(391,110)])
link(X2,7875420:Var2,[])
AddHint(47,12,55,13,MathStr)
}
Add(MathParse,1835425,322,329)
{
MathStr="(%1+%2)"
link(X1,381117:Var2,[])
link(X2,12674061:Var1,[(335,117)])
AddHint(47,10,55,13,MathStr)
}
Add(Label,3837647,224,378)
{
Left=280
Top=60
Width=10
Height=17
Caption="0"
}
Add(Label,5514199,224,182)
{
Left=280
Top=20
Width=10
Height=17
Caption="0"
}
Add(Label,5684404,273,378)
{
Left=145
Top=60
Width=100
Height=17
Caption="MathParse: "
}
Add(Label,2750348,273,182)
{
Left=145
Top=20
Width=100
Height=17
Caption="MathParseEx:"
}
Add(Button,8742485,35,343)
{
Left=20
Top=15
Width=110
Caption="Test 01"
link(onClick,8604457:doEvent1,[])
}
Add(Hub,8604457,105,343)
{
OutCount=6
link(onEvent1,14100898:doStart,[(130,349)(130,181)])
link(onEvent2,14100898:doStop,[(137,356)(137,188)])
link(onEvent3,16096533:doStart,[(144,363)(144,279)])
link(onEvent4,16096533:doStop,[(151,370)(151,286)])
link(onEvent5,955542:doStart,[])
link(onEvent6,955542:doStop,[])
}
Add(Edit,11617021,322,42)
{
Left=20
Top=45
Text="3.1"
DataType=4
}
Add(Edit,8004220,392,42)
{
Left=80
Top=45
Text="2.7"
DataType=4
}
Add(For,7769855,245,133)
{
End=1000
link(onEvent,204878:doCalc,[])
AddHint(-67,16,39,13,End)
}
Add(For,2646223,245,329)
{
End=1000
link(onEvent,1835425:doCalc,[])
AddHint(-66,14,39,13,End)
}
Add(TimeCounter,14100898,168,175)
{
Precision=1
link(onStart,7769855:doFor,[(207,181)(207,139)])
link(onStop,5514199:doText,[])
}
Add(TimeCounter,955542,168,371)
{
Precision=1
link(onStart,2646223:doFor,[(207,377)(207,335)])
link(onStop,3837647:doText,[])
}
Add(GetDataEx,381117,322,105)
{
link(Data,11617021:Text,[])
}
Add(GetDataEx,7875420,392,112)
{
link(Data,8004220:Text,[])
}
Add(MathParseEx,11208601,805,133)
{
DataCount=4
MathStr="(%1+%2) + 1/(%1+%2) + 1/(1+%1+%2) + 1/(2+%1+%2) + 1/(3+%1+%2) + 1/(4+%1+%2) + 1/(5+%1+%2) + 1/(6+%1+%2) + 1/(7+%1+%2) + 1/(8+%1+%2) + 1/(9+%1+%2)"
Point(onError)
link(X1,13986686:Var3,[(811,110)])
link(X2,9333203:Var2,[])
AddHint(48,5,196,65,MathStr)
}
Add(MathParse,9132160,742,329)
{
DataCount=4
MathStr="(%1+%2) + 1/(%1+%2) + 1/(1+%1+%2) + 1/(2+%1+%2) + 1/(3+%1+%2) + 1/(4+%1+%2) + 1/(5+%1+%2) + 1/(6+%1+%2) + 1/(7+%1+%2) + 1/(8+%1+%2) + 1/(9+%1+%2)"
link(X1,4971951:Var2,[])
link(X2,10617285:Var1,[(755,117)])
AddHint(47,10,196,65,MathStr)
}
Add(Label,14667652,644,378)
{
Left=280
Top=135
Width=10
Height=17
Caption="0"
}
Add(Label,3186479,644,182)
{
Left=280
Top=95
Width=10
Height=17
Caption="0"
}
Add(Label,16084072,693,378)
{
Left=145
Top=135
Width=100
Height=17
Caption="MathParse: "
}
Add(Label,5159161,693,182)
{
Left=145
Top=95
Width=100
Height=17
Caption="MathParseEx:"
}
Add(Button,9927697,455,343)
{
Left=20
Top=90
Width=110
Caption="Test 10"
link(onClick,635105:doEvent1,[])
}
Add(Hub,635105,525,343)
{
OutCount=6
link(onEvent1,10011126:doStart,[(550,349)(550,181)])
link(onEvent2,10011126:doStop,[(557,356)(557,188)])
link(onEvent3,12618441:doStart,[(564,363)(564,279)])
link(onEvent4,12618441:doStop,[(571,370)(571,286)])
link(onEvent5,13392031:doStart,[])
link(onEvent6,13392031:doStop,[])
}
Add(Edit,4457363,742,42)
{
Left=20
Top=120
Text="3.1"
DataType=4
}
Add(Edit,42559,812,42)
{
Left=80
Top=120
Text="2.7"
DataType=4
}
Add(For,16498081,665,133)
{
End=1000
link(onEvent,11208601:doCalc,[])
AddHint(-67,16,39,13,End)
}
Add(For,2675870,665,329)
{
End=1000
link(onEvent,9132160:doCalc,[])
AddHint(-66,14,39,13,End)
}
Add(TimeCounter,10011126,588,175)
{
Precision=1
link(onStart,16498081:doFor,[(627,181)(627,139)])
link(onStop,3186479:doText,[])
}
Add(TimeCounter,13392031,588,371)
{
Precision=1
link(onStart,2675870:doFor,[(627,377)(627,335)])
link(onStop,14667652:doText,[])
}
Add(GetDataEx,4971951,742,105)
{
link(Data,4457363:Text,[])
}
Add(GetDataEx,9333203,812,112)
{
link(Data,42559:Text,[])
}
Add(Label,4194723,224,280)
{
Left=280
Top=40
Width=10
Height=17
Caption="0"
}
Add(Label,3867639,273,280)
{
Left=145
Top=40
Width=100
Height=17
Caption="MathParseFast: "
}
Add(For,1517355,245,231)
{
End=1000
link(onEvent,11847314:doCalc,[])
AddHint(-66,14,39,13,End)
}
Add(TimeCounter,16096533,168,273)
{
Precision=1
link(onStart,1517355:doFor,[(207,279)(207,237)])
link(onStop,4194723:doText,[])
}
Add(FastMathParse,11847314,350,231)
{
MathStr="(%1+%2)"
link(X1,13913289:Var2,[])
link(X2,12674061:Var2,[])
AddHint(50,9,55,13,MathStr)
}
Add(GetDataEx,13913289,350,105)
{
Angle=3
link(Data,381117:Var3,[])
}
Add(GetDataEx,12674061,357,112)
{
Angle=1
link(Data,7875420:Var1,[])
}
Add(Label,9109861,644,280)
{
Left=280
Top=115
Width=10
Height=17
Caption="0"
}
Add(Label,9040181,693,280)
{
Left=145
Top=115
Width=100
Height=17
Caption="MathParseFast: "
}
Add(For,7160229,665,231)
{
End=1000
link(onEvent,12868420:doCalc,[])
AddHint(-66,14,39,13,End)
}
Add(TimeCounter,12618441,588,273)
{
Precision=1
link(onStart,7160229:doFor,[(627,279)(627,237)])
link(onStop,9109861:doText,[])
}
Add(FastMathParse,12868420,770,231)
{
MathStr="(%1+%2) + 1/(%1+%2) + 1/(1+%1+%2) + 1/(2+%1+%2) + 1/(3+%1+%2) + 1/(4+%1+%2) + 1/(5+%1+%2) + 1/(6+%1+%2) + 1/(7+%1+%2) + 1/(8+%1+%2) + 1/(9+%1+%2)"
link(X1,13986686:Var2,[])
link(X2,10617285:Var2,[])
AddHint(50,9,196,65,MathStr)
}
Add(GetDataEx,13986686,770,105)
{
Angle=3
link(Data,4971951:Var3,[])
}
Add(GetDataEx,10617285,777,112)
{
Angle=1
link(Data,9333203:Var1,[])
}

Что важно: и в тесте 01, и в тесте 10 - одинаковое число интерфейсных манипуляций. Но очень разный объем вычислений.
И вот только теперь можно попробовать "вычесть". И не ранее.
Ну, и "кто кого гораздо больше"
И никогда не парьте мне могзи про то, что Fast "в разы" быстрее там чего-то. Потому что в сотни разов


Короче, не побоюсь повториться, но: Эксперимент -- это Вам не баб щупать






------------ Дoбавленo в 14.21:
Assasin писал(а):
Это тогда надо строить дерево выражения, как я понимаю. Если подскажешь метод, как обойтись без него и не переделывать парсер снова, то можно добавить.

Не надо ничего усложнять.
Все уже есть, вообще-то говоря.
Вычисления - есть в оригинальном (с которого разбор ты и срисовывал)
Кодирование - ты уже написал.

Надо просто их "скрестить".
Ну типа: результатом работы LevelXXX является либо КОД (уже записанный в TProgram), либо вычисленная КОНСТАНТА.
((как об этом догадается вызывающий - ну придумаем чего ни то...))
Если (к примеру) ты складываешь две константы - то возвращаешь результат этого сложения вызывающему, и обзываешь его КОНСТАНТОЙ.
Если один из операндов переменная - генерируешь соответствующий КОД.

Но подробности -- чуток по-позже...
Ничего военного, в общем
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#22: 2014-06-17 14:58:31 ЛС | профиль | цитата
Galkov писал(а):
Вот, смотрите код. ЭКСПЕРИМЕНТ делается примерно так:

Не, если так рассуждать, это тоже какая-то ерунда. Что же это за эксперимент, в котором погрешность больше 5%? Попробовал пожать несколько раз на кнопку "Test01", получил цифры для MathParseEx от 9к до 21к, у FastMathParse от 7к до 11к, и от 9к до 11к. Слишком мало итераций и слишком большой разброс в итоге.
Galkov писал(а):
И никогда не парьте мне могзи про то, что Fast "в разы" быстрее там чего-то. Потому что в сотни разов

Я уверен, что алгоритм вычислений в FastMathParse прекрасно реализован, хоть и не разбирал его. Тем не менее, в первую очередь, хочется видеть реальную пользу на практике и при больших количествах итераций...
...
Пока писал пост, стало понятно, что спорить тут бесполезно, т.к. нет исследования, в котором определялась частота применения MathParse в различных случаях. И тем не менее, нет ли таких тестов, которые не дают такого большого разброса в цифрах?
карма: 10
0
Ответов: 9906
Рейтинг: 351
#23: 2014-06-17 18:45:20 ЛС | профиль | цитата
Assasin писал(а):
получил цифры для MathParseEx от 9к до 21к

У тебя АНБ считывает все твои пароли, и отправляет на свой сервер. Это же тоже время занимает.

А вообще, ты чего до меня докопался, если у тебя ось (антивирус, или еще хрен его знает чего) считает себя важнее, чем твоя задача
У меня, прямо сейчас, получаются цифры для MathParseEx от 13.7к до 13.9к (от 34.0к до 34.3к - для теста 10)
XP-SP3, одно ядро с 2.13ГГц.
На работе побыстрее будет: от 8.6к до 8.8к (по памяти)

Assasin писал(а):
Не, если так рассуждать, это тоже какая-то ерунда

Это не "рассуждения", это вычисление. И даже 5%-ный разброс - это значительно более сильное утверждение, чем "видно же, что в разы".
А точность измерений есть в любом эксперименте. И это вовсе не ерунда, а "Великая Сермяжная Правда".
Просто ее надо учитывать, когда делаешь некоторое утверждение.

Следующий вариант для обсуждения (в полном соответствии с "... тут думать надо"): видимо, настоящим временем является нижняя граница измерений.
Наш вычислительный процесс - полностью же детерминированный. 1000 раз выполняются одни и те же операции. Иногда вмешивается АНБ, и тратит наше процессорное время. Минимум, видимо (???), когда это было чисто наше время (враги клювом прощелкали).

Это для обсуждения.
Косвенное подтверждение: разброс сильно уменьшается за счет "максимальных значений", при увеличении приоритета процесса "ручками" (через диспетчер задач).


------------ Дoбавленo в 18.45:
Assasin, я тебе один умный вещь скажу... Только ты не обижайся

Оставлять варнинги - НИЗЯ. Просто - НИЗЯ, и все. Без диспутов и обсуждений.

Да, порой компилятор тупит. Приходится лишние строки вводить...
В твоем случае - ступил всего пару раз.
НО, в reCalc - реальная ошибка. По-моему.
карма: 9

1
Голосовали:Assasin
Ответов: 4628
Рейтинг: 749
#24: 2014-06-17 18:52:20 ЛС | профиль | цитата
[offtop]
Если ворнингов никак не удаётся избежать (либо нерационально - добавлять пустой код), я делаю так:


#pas
unit UnitName;

{$IFNDEF FPC}{$HINTS OFF}{$ENDIF}
{$WARNINGS OFF}


........................



{$IFNDEF FPC}{$HINTS ON}{$ENDIF}
{$WARNINGS ON}

end.
На время тестирования комментирую, просматриваю, о чем он там предупреждает, затем опять включаю.

И ещё, там в WinLayout.pas по моей инициативе было добавлено отключение ворнингов, но я забыл, что в Delphi это отключение действует глобально (в FPC - только для текущего модуля). Поэтому стоило бы добавить включение в конце модуля (а лучше, привести к вышеприведенному)...
[/offtop]
карма: 26

0
Разработчик
Ответов: 4698
Рейтинг: 426
#25: 2014-06-17 19:05:12 ЛС | профиль | цитата
Galkov писал(а):
НО, в reCalc - реальная ошибка. По-моему.

Да, верно. Delphi4 почему-то варнинги вообще не показывает, придется FPC компилить и смотреть, что он выдает.
Обновил архив.
карма: 10
0
Ответов: 4628
Рейтинг: 749
#26: 2014-06-17 19:16:57 ЛС | профиль | цитата
Удали 3-4 строки в WinLayout.pas...
------------ Дoбавленo в 19.16:
Вот правленный WinLayout: winlayout 2014-06-17.7z
Кто может - коммитните на SVN
карма: 26

1
Голосовали:Assasin
Ответов: 9906
Рейтинг: 351
#27: 2014-06-17 19:32:35 ЛС | профиль | цитата
Assasin писал(а):
Delphi4 почему-то варнинги вообще не показывает

У меня показывает - вот про них и говорил...
"%fname%" "-U%opath%." -UD:\Programs\HiAsm\Compiler\Kol1 -Q -GD -E%opath%

((на папку "своего" KOL-а - можно внимания не обращать))

Редактировалось 1 раз(а), последний 2017-08-05 11:06:26
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#28: 2014-06-17 19:38:51 ЛС | профиль | цитата
Сделал новые тесты по схеме Galkov, изменив количество итераций цикла в 10 раз больше и поставив приоритет реального времени процессу в диспетчере задач:

Можно сделать вывод, что процесс вычислений занимает (от общего времени):
MathParseEx: ~54.4%
FastMathParse: ~0.1% (даже не вычислял)
MathParse: ~74.4%

Итого, MathParseEx быстрее MathParse (по вычислениям) примерно в 3 раза (учитывая заданную формулу).

P.S.: таки я оказался прав У меня вычисления дороже стрельбы по точкам.
------------ Дoбавленo в 19.38:
Galkov, там суть не в флагах компиляции, а в
Netspirit писал(а):
Удали 3-4 строки в WinLayout.pas...

карма: 10
0
Ответов: 9906
Рейтинг: 351
#29: 2014-06-17 19:50:06 ЛС | профиль | цитата
Вот, проба пера для "минимального времени"...
mathparsetest_mini.png
типа минут пять подождал
------------ Дoбавленo в 19.50:
Assasin писал(а):
У меня вычисления дороже стрельбы по точкам.

А не факт

А вот факт в том, что если БЫ улучшить "собственную скорость" в пару раз....
То замахаются юзеры формулу сочинять, чтобы заметить "задержки вычислений"

Лично мне именно так кажется
карма: 9

0
файлы: 2mathparsetest_mini.png [10.7KB] [443], mathparseextest_a.sha [6.5KB] [585]
Разработчик
Ответов: 4698
Рейтинг: 426
#30: 2014-06-17 20:29:57 ЛС | профиль | цитата
Galkov писал(а):
Ну типа: результатом работы LevelXXX является либо КОД (уже записанный в TProgram), либо вычисленная КОНСТАНТА.

Идея ясна. Я думал немного иначе: оптимизировать все по максимуму. Подход, который ты предложил, например, не сможет оптимизировать выражение 2*(3+%1+4) в 14+2*%1 (поэтому то я сначала в сторону дерева и думал - там-то можно в процессе обработки дерева смотреть аргументы по левой ветви и по правой, а также переставлять местами операции одного приоритета, чтобы в примере выше компилятор мог упростить 3+%1+4 до 7+%1, ну а потом и далее).
Ну а так, можно и без дерева, да, это можно сделать, не сложно вроде бы.
карма: 10
0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)