Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 4680
Рейтинг: 423
#1: 2014-06-09 01:35:51 ЛС | профиль | цитата
[offtop]Давным-давно я хотел сделать свой парсер математики с возможностью записи нескольких формул в одном компоненте (например, чтоб все корни квадратного уравнения считать ), но так руки и не дошли, появились дела и идея заглохла. Вчера голову посетила навязчивая идея: уже же есть навороченный и медленный парсер математики и простой и быстрый компилятор математики. Так почему бы не попытаться совместить два этих компонента? Так родился MathParserEx. (Кстати, изначально он планировался как полная замена MathParser, но пока этого делать нельзя. Почему - далее).[/offtop]

Итак, MathParserEx, в чем его особенности:

  • Полностью копирует функционал MathParser
  • Построен на технологии компиляции в байт-код и его последующего исполнения своей стековой ВМ, что делает его в разы быстрее MathParser.
  Как это работает?
  Сначала компоненту подается на вход строка - выражение, которое он будет считать. Парсер разбирает это выражение и компилирует его в опкоды. После этого входная строка в общем-то и не нужна, программа уже есть в памяти.
В чем отличие от FastMathParser?
В FastMathParser происходит компиляция напрямую в коды процессора, что делает компонент непереносимым на другие архитектуры. Байт-код, который использует MathParserEx, не привязан к архитектуре процессора, поэтому компонент гораздо легче протируем на другие процессоры. Но, конечно же, за это приходится платить небольшим ухудшением производительности.
Когда дергаем точку doCalc, происходит выполнение этой программы, т.е. еще раз парсить выражение не надо. За счет этого и происходит значительный прирост производительности.

  Что еще не реализовано?
  На данный момент нет возможности при возникновении вычислительной ошибки узнать, в каком месте исходного выражения она произошла. Реализация этого может привести к падению производительности за счет того, что придется увеличить объем получаемого байт-кода (из-за вставки отладочной инфы), скорее всего будет сделано два режима работы компонента: debug (доступен просмотр позиций ошибок вычисления) и release (недоступен просмотр).
UPD: уже реализовано

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

Кстати, заметил одну интересную особенность: есть свойство ResultType, определяющее, будет ли целым результат. Но когда мы повторно используем результат через %0 в выражении, подставляется вещественный результат, что в итоге может привести к неожиданным результатам вычислений. Может, стоит пофиксить такое поведение?

P.S.: тестовая схема выдает у меня двукратный прирост производительности на компиляторе Delphi 4 и трехкратный на FPC 1.9.6.
P.P.S.: Компонент и тестовая схема приложены в архиве вот здесь внизу:
||
||
/
карма: 10
7
файлы: 2mathparseex.rar [12.3KB] [217], mathparseex_v1.3.rar [13.5KB] [213]
Голосовали:nesco, ser_davkin, foksov, sla8a, MAV, Dseren, Konst
vip
#1.1контекстная реклама от партнеров
Разработчик
Ответов: 25681
Рейтинг: 2087
#2: 2014-06-09 02:16:42 ЛС | профиль | цитата
Подождем, что скажет начальник транспортного цеха.
карма: 20

0
Ответов: 9906
Рейтинг: 351
#3: 2014-06-09 09:30:50 ЛС | профиль | цитата
Может (!!!) и не в тему - но "начальником" я себя не считаю.
Собственно, все "начальники" (ака - Разработчики) прописаны в <About>

Мнение - ну быстрее должно быть. Если код грамотно писать, конечно же.
Сам бы никогда этим не стал заниматься. В моем понимании - тупиковое это направление, всякие там байт-коды, Пи-коды, и т.п.. Кажется и Кладов такой фигней (про KOL) страдал... Здорово напоминает героическое преодоление трудностей, которые тебе кто-то создал. Ну типа, сначала кладем асфальт, потом начинаем прокладывать под ним трубы...

Но это - философия.
А по делу: если Коллега чувствует в себе достаточно здоровья для поддержки такой техники - так давайте порадуемся за него.
Мы же его знаем - мозги есть, тупить то не должен.
Нужны будут помощь и консультации - да пожалуйста.
В общем, ничего нового не сказал
------------ Дoбавленo в 09.30:
Да, добавлю...
Задача, которую пытается решить коллега Assasin, практически ничем не отличается от FastMathParser
Просто другой Target.
Получается, что нам надо сделать (выделить из него нужные шматочки, и заменить на свои) мультиплатформенный FastMathParser...
карма: 9

1
Голосовали:foksov
Разработчик
Ответов: 4680
Рейтинг: 423
#4: 2014-06-09 12:01:45 ЛС | профиль | цитата
Galkov писал(а):
Получается, что нам надо сделать (выделить из него нужные шматочки, и заменить на свои) мультиплатформенный FastMathParser...

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

По-хорошему, да, надо компилить всегда в код целевого процессора, но по ряду причин, таких как незнание ассемблера на достаточном уровне, сложность реализации мультиплатформенности, сумасшедшая поддержка всего этого дела потом,... Поэтому байт-код показался для меня приемлемым вариантом: и производительность ощутимо возрастет, и реализовывать/поддерживать байт-код проще.
Galkov писал(а):
Мнение - ну быстрее должно быть. Если код грамотно писать, конечно же.
Galkov писал(а):
Нужны будут помощь и консультации - да пожалуйста.

Если найдется свободная минутка, буду признателен за общий осмотр кода. В основе у меня все так же лежит парсер от MathParse и многие части кода просто подстроены под окружение ВМ.
Galkov писал(а):
достаточно здоровья для поддержки такой техники

Да она в принципе не сложная, если вечером посидеть, то времени должно хватить и на просмотр фильма.
------------ Дoбавленo в 12.01:
Интересные результаты однако

Add(Button,2913659,168,462)
{
Left=155
Top=10
Caption="Test2"
link(onClick,12093841:doEvent1,[])
}
Add(Label,8109926,343,511)
{
Left=320
Top=10
Width=10
Height=17
Caption="0"
}
Add(Label,3091122,343,651)
{
Left=320
Top=30
Width=10
Height=17
Caption="0"
}
Add(Label,15258225,343,805)
{
Left=320
Top=50
Width=10
Height=17
Caption="0"
}
Add(MathParseEx,10679677,588,462)
{
DataCount=4
MathStr="%2*%1^2 + %3*%1 + %4"
link(X1,161968:Var3,[(594,450)])
link(X2,5062901:Var3,[(601,443)])
link(X3,5695714:Var3,[(608,436)])
link(X4,5126503:Var3,[(615,429)])
AddHint(1,40,129,13,MathStr)
}
Add(VisualStrings,148062,434,399)
{
Lines=#1:2|
}
Add(VisualStrings,16148217,476,399)
{
Lines=#1:3|
}
Add(VisualStrings,8135429,518,399)
{
Lines=#1:4|
}
Add(VisualStrings,9697363,392,399)
{
Lines=#2:20|
}
Add(For,4276286,343,462)
{
End=100000
link(onEvent,10679677:doCalc,[])
link(onStop,16370378:doStop,[(387,475)(387,456)(274,456)(274,475)])
AddHint(-20,-62,51,13,End)
}
Add(TimeCounter,16370378,287,462)
{
link(onStart,4276286:doFor,[])
link(onStop,8109926:doText,[(331,475)(331,517)])
}
Add(Hub,12093841,217,462)
{
OutCount=3
link(onEvent1,16370378:doStart,[])
link(onEvent2,10850824:doStart,[(259,475)(259,587)])
link(onEvent3,11599641:doStart,[(251,482)(251,741)])
}
Add(MathParse,2704163,588,581)
{
DataCount=4
MathStr="%2*%1^2 + %3*%1 + %4"
link(X1,14668200:Var3,[(594,562)])
link(X2,16503595:Var3,[(601,556)])
link(X3,7233213:Var3,[(608,549)])
link(X4,6143149:Var3,[(615,543)])
AddHint(0,44,129,13,MathStr)
}
Add(GetDataEx,161968,392,445)
{
link(Data,9697363:Text,[])
}
Add(GetDataEx,5062901,434,438)
{
link(Data,148062:Text,[])
}
Add(GetDataEx,5695714,476,431)
{
link(Data,16148217:Text,[])
}
Add(GetDataEx,5126503,518,424)
{
link(Data,8135429:Text,[])
}
Add(For,12290167,343,581)
{
End=100000
link(onEvent,2704163:doCalc,[])
link(onStop,10850824:doStop,[(387,594)(387,575)(274,575)(274,594)])
AddHint(-6,43,51,13,End)
}
Add(TimeCounter,10850824,287,581)
{
link(onStart,12290167:doFor,[])
link(onStop,3091122:doText,[(331,594)(331,657)])
}
Add(FastMathParse,5785906,588,735)
{
DataCount=4
MathStr="%2*%1^2 + %3*%1 + %4"
link(X1,14668200:Var2,[(594,654)(398,654)])
link(X2,16503595:Var2,[(601,651)(440,651)])
link(X3,7233213:Var2,[(608,648)(482,648)])
link(X4,6143149:Var2,[(615,644)(524,644)])
AddHint(2,47,129,13,MathStr)
}
Add(GetDataEx,14668200,392,557)
{
link(Data,161968:Var2,[])
}
Add(GetDataEx,16503595,434,551)
{
link(Data,5062901:Var2,[])
}
Add(GetDataEx,7233213,476,544)
{
link(Data,5695714:Var2,[])
}
Add(GetDataEx,6143149,518,538)
{
link(Data,5126503:Var2,[])
}
Add(For,12719809,343,735)
{
End=100000
link(onEvent,5785906:doCalc,[])
link(onStop,11599641:doStop,[(387,748)(387,729)(274,729)(274,748)])
AddHint(-6,43,51,13,End)
}
Add(TimeCounter,11599641,287,735)
{
link(onStart,12719809:doFor,[])
link(onStop,15258225:doText,[(331,748)(331,811)])
}
карма: 10
0
Ответов: 9906
Рейтинг: 351
#5: 2014-06-09 14:20:56 ЛС | профиль | цитата
Тупо навскидку вопрос возник

#pas
.....
CmdMatr: // [n:byte] матрица из точки %n
begin
if not FProgram.ReadByte(i) then begin Err := 2; Exit; end;
Mtx := ReadMatrix(self.X[i]);
if Mtx=nil then begin Err :=1 ; exit; end;
if not FStack.Pop(y) then begin Err := 1; Exit; end;
if not FStack.Pop(x) then begin Err := 1; Exit; end;
mx := round(y); my := round(x);
Fd := Mtx._Get(mx, my);
if _IsNull(Fd) then begin Err:=1; exit; end;
FStack.Push(ToReal(Fd));
end;
.....
Скажи мне друг любезный: в FProgam кто коды пихал - ты сам, или злой бабайка
Который может сотворить "диверсию", чтобы не сработали FProgram.ReadByte, FStack.Pop...
------------ Дoбавленo в 14.20:
Вечером поподробнее отпишусь
Не "навскидку" уже
карма: 9

0
Ответов: 8607
Рейтинг: 800
#6: 2014-06-09 14:20:59 ЛС | профиль | цитата
Assasin, на формулах "sqrt(sqr(sin(%1))+sqr(cos(%1)))" и "ln(%1)+lg(%1)+sin(%1)+cos(%1)" где %1=i разница на порядок (в ДЕСЯТЬ раз). Для полноты счастья надо сравнить с IC.
карма: 18

0
Разработчик
Ответов: 4680
Рейтинг: 423
#7: 2014-06-09 14:50:00 ЛС | профиль | цитата
Galkov писал(а):
Скажи мне друг любезный: в FProgam кто коды пихал - ты сам, или злой бабайка

Это уже в привычку вошло, что всегда лучше один раз вставить "лишнюю" проверку, чем потом часами искать в чем собака зарылась
Леонид писал(а):
разница на порядок (в ДЕСЯТЬ раз). Для полноты счастья надо сравнить с IC.

Круто. Видать из-за сравнения строк (поиск индекса нужной функции) выигрыш идет. IC сейчас сделаю.
------------ Дoбавленo в 14.41:
И все-таки не пойму, почему FastMathParse так в скорости проигрывает даже штатному MathParse
------------ Дoбавленo в 14.50:
А, все, понял, в чем дело, в FastMathParse нет возведения в степень, в итоге он каждый раз перед расчетом компилил выражение и выдавал ошибку. Вот это больше похоже на правду:

Add(Button,2913659,168,462)
{
Left=155
Top=10
Caption="Test2"
link(onClick,12093841:doEvent1,[])
}
Add(Label,4742312,98,329)
{
Left=240
Top=10
Width=70
Height=17
Caption="MathParseEx:"
}
Add(Label,7945742,98,371)
{
Left=240
Top=30
Width=58
Height=17
Caption="MathParse:"
}
Add(Label,34978,98,413)
{
Left=240
Top=50
Width=78
Height=17
Caption="FastMathParse:"
}
Add(Label,4733123,343,959)
{
Left=320
Top=70
Width=10
Height=17
Caption="0"
}
Add(Label,2989583,91,406)
{
Left=240
Top=70
Width=14
Height=17
Caption="IC"
}
Add(Label,2361388,777,882)
{
Left=400
Top=70
Width=21
Height=17
Caption="Result"
}
Add(Label,6441935,777,462)
{
Left=400
Top=10
Width=21
Height=17
Caption="Result"
}
Add(Label,7850955,777,581)
{
Left=400
Top=30
Width=21
Height=17
Caption="Result"
}
Add(Label,13608767,777,735)
{
Left=400
Top=50
Width=21
Height=17
Caption="Result"
}
Add(MathParseEx,10679677,588,462)
{
DataCount=4
MathStr="%2*%1*%1 + %3*%1 + %4"
link(onResult,14764415:doWork,[])
link(X1,161968:Var3,[(594,446)])
link(X2,5062901:Var3,[(601,439)])
link(X3,5695714:Var3,[(608,432)])
link(X4,5126503:Var3,[(615,425)])
AddHint(1,40,135,13,MathStr)
}
Add(VisualStrings,148062,434,399)
{
Lines=#1:2|
}
Add(VisualStrings,16148217,476,399)
{
Lines=#1:3|
}
Add(VisualStrings,8135429,518,399)
{
Lines=#1:4|
}
Add(VisualStrings,9697363,392,399)
{
Lines=#2:20|
}
Add(For,4276286,343,462)
{
End=100000
link(onEvent,10679677:doCalc,[])
link(onStop,16370378:doStop,[(387,475)(387,456)(274,456)(274,475)])
AddHint(-20,-62,51,13,End)
}
Add(TimeCounter,16370378,287,462)
{
link(onStart,4276286:doFor,[])
link(onStop,8109926:doText,[(331,475)(331,517)])
}
Add(Hub,12093841,217,462)
{
OutCount=4
link(onEvent1,16370378:doStart,[])
link(onEvent2,10850824:doStart,[(259,475)(259,587)])
link(onEvent3,11599641:doStart,[(251,482)(251,741)])
link(onEvent4,8557430:doStart,[(242,489)(242,888)])
}
Add(MathParse,2704163,588,581)
{
DataCount=4
MathStr="%2*%1*%1 + %3*%1 + %4"
link(onResult,1133859:doWork,[])
link(X1,14668200:Var3,[(594,558)])
link(X2,16503595:Var3,[(601,551)])
link(X3,7233213:Var3,[(608,544)])
link(X4,6143149:Var3,[(615,537)])
AddHint(0,44,135,13,MathStr)
}
Add(GetDataEx,161968,392,441)
{
link(Data,9697363:Text,[])
}
Add(GetDataEx,5062901,434,434)
{
link(Data,148062:Text,[])
}
Add(GetDataEx,5695714,476,427)
{
link(Data,16148217:Text,[])
}
Add(GetDataEx,5126503,518,420)
{
link(Data,8135429:Text,[])
}
Add(For,12290167,343,581)
{
End=100000
link(onEvent,2704163:doCalc,[])
link(onStop,10850824:doStop,[(387,594)(387,575)(274,575)(274,594)])
AddHint(-6,43,51,13,End)
}
Add(TimeCounter,10850824,287,581)
{
link(onStart,12290167:doFor,[])
link(onStop,3091122:doText,[(331,594)(331,657)])
}
Add(FastMathParse,5785906,588,735)
{
DataCount=4
MathStr="%2*%1*%1 + %3*%1 + %4"
Point(onError)
link(onResult,7653910:doWork2,[])
link(X1,478193:Var3,[(594,663)])
link(X2,1694588:Var3,[(601,649)])
link(X3,4358536:Var3,[(608,642)])
link(X4,16328891:Var3,[(615,635)])
link(onError,7653910:doWork3,[(655,748)])
AddHint(2,47,135,13,MathStr)
}
Add(GetDataEx,14668200,392,553)
{
link(Data,161968:Var2,[])
}
Add(GetDataEx,16503595,434,546)
{
link(Data,5062901:Var2,[])
}
Add(GetDataEx,7233213,476,539)
{
link(Data,5695714:Var2,[])
}
Add(GetDataEx,6143149,518,532)
{
link(Data,5126503:Var2,[])
}
Add(For,12719809,343,735)
{
End=100000
link(onEvent,5785906:doCalc,[])
link(onStop,11599641:doStop,[(387,748)(387,729)(274,729)(274,748)])
AddHint(-6,43,51,13,End)
}
Add(TimeCounter,11599641,287,735)
{
link(onStart,12719809:doFor,[])
link(onStop,15258225:doText,[(331,748)(331,811)])
}
Add(HubEx,7653910,651,735)
{
link(onEvent,5213823:doWork,[])
}
Add(InlineCode,6185762,588,882)
{
WorkPoints=#6:doWork|
EventPoints=#7:onEvent|
VarPoints=#2:vr|
DataPoints=#4:dat1|4:dat2|4:dat3|4:dat4|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|22: onEvent:THI_Event;|4: |19: dat1:THI_Event;|19: dat2:THI_Event;|19: dat3:THI_Event;|19: dat4:THI_Event;|4: |50: procedure doWork(var _Data:TData; Index:word);|5: end;|0:|14:implementation|0:|29:procedure THiAsmClass.doWork;|25:var x1, x2, x3, x4: real;|5:begin|33: x1 := ReadReal(_Data, dat1, 0);|33: x2 := ReadReal(_Data, dat2, 0);|33: x3 := ReadReal(_Data, dat3, 0);|33: x4 := ReadReal(_Data, dat4, 0);|2: |46: _hi_OnEvent(onEvent, x2*x1*x1 + x3*x1 + x4);|4:end;|0:|4:end.|
link(onEvent,8147195:doWork,[])
link(dat1,478193:Var2,[(594,851)(398,851)])
link(dat2,1694588:Var2,[(601,835)(440,835)])
link(dat3,4358536:Var2,[(608,820)(482,820)])
link(dat4,16328891:Var2,[(615,811)(524,811)])
}
Add(For,14266523,343,882)
{
End=100000
link(onEvent,6185762:doWork,[])
link(onStop,8557430:doStop,[(387,895)(387,876)(274,876)(274,895)])
AddHint(-6,43,51,13,End)
}
Add(TimeCounter,8557430,287,882)
{
link(onStart,14266523:doFor,[])
link(onStop,4733123:doText,[(331,895)(331,965)])
}
Add(GetDataEx,478193,392,658)
{
link(Data,14668200:Var2,[])
}
Add(GetDataEx,1694588,434,644)
{
link(Data,16503595:Var2,[])
}
Add(GetDataEx,4358536,476,637)
{
link(Data,7233213:Var2,[])
}
Add(GetDataEx,16328891,518,630)
{
link(Data,6143149:Var2,[])
}
Add(Check,14764415,665,462)
{
Check=1
link(onEvent,6441935:doText,[])
}
Add(Check,1133859,665,581)
{
Check=1
link(onEvent,7850955:doText,[])
}
Add(Check,5213823,679,735)
{
Check=1
link(onEvent,13608767:doText,[])
}
Add(Check,8147195,672,882)
{
Check=1
link(onEvent,2361388:doText,[])
}
Add(Label,15258225,343,805)
{
Left=320
Top=50
Width=10
Height=17
Caption="0"
}
Add(Label,3091122,343,651)
{
Left=320
Top=30
Width=10
Height=17
Caption="0"
}
Add(Label,8109926,343,511)
{
Left=320
Top=10
Width=10
Height=17
Caption="0"
}
карма: 10
0
Ответов: 9906
Рейтинг: 351
#8: 2014-06-09 15:32:58 ЛС | профиль | цитата
Assasin писал(а):
Это уже в привычку вошло, что всегда лучше один раз вставить "лишнюю" проверку, чем потом часами искать в чем собака зарылась

Это категорически неправильная привычка
Правильная -- это ПРЕДЫДУЩИЙ код делать с нулевым количеством ошибок. Лучше в два раза больше времени потратить на отладку модуля, и быть уверенным, что в нем НОЛЬ ошибок, "чем потом часами искать в чем собака зарылась".

Это две разные концепции.
Но вспомни концепцию самого элемента: ОН ДОЛЖЕН РАБОТАТЬ БЫСТРО. Ты ведь для этого его делал
Так вот, это противоречит первой, но полностью соответствует второй технологии.
У второй концепции есть одна беда: время "100%-ного вылизывания" очень сильно зависит от объема кодов. Может быть даже и экспоненциально...
Тут выход только один (который я знаю) -- ограничить волевым усилием размеры одного (безошибочного) модуля.

Скажем -- 300 строк кода. Вполне реально вылизать "на ноль ошибок" за разумное время.
100 строк кода -- еще реальнее.
А уж 30 -- вообще без проблем
------------ Дoбавленo в 15.32:
Извините, расфилософствовался чего-то
карма: 9

0
Разработчик
Ответов: 4680
Рейтинг: 423
#9: 2014-06-09 17:23:22 ЛС | профиль | цитата
Обновил компонент и отладочную схему (в первом посте).
Реализовал отладочный режим. По-умолчанию компонент находится в отладочном режиме, изменяется свойством DebugMode.
Тесты показали, что в отладочном режиме производительность падает в ~2 раза (но по прежнему есть выигрыш перед MathParse).
Galkov писал(а):
Правильная -- это ПРЕДЫДУЩИЙ код делать с нулевым количеством ошибок.

Ну это уже утопия. Можно быть на 100% уверенным, что ошибок нет, но на самом-то деле (луркой запахло) ) одна очень незаметная мелочь сидит и ждет своего момента (как например с недавно нашумевшей HeartBleed в OpenSSL).
Если бы было возможно писать идеальный код за разумное время, думаю, сейчас мир софта был бы совсем другим, и не было бы вон той забавной фичи, позволявшей в игрушке на сеге проходить сквозь сцены, и вон той другой фичи, с помощью которой можно обойти вон тот баг, и этого веселого бага с... Увлекся я философией тоже
НО! В качестве теста допустимо убрать проверки, и если быстродействие ощутимо повысится (без фатального вреда для всей программы), то можно и зарелизить без проверок.
------------ Дoбавленo в 17.23:
Потестил: что с проверками, что без, выдает одни и те же цифры. Файлик приложил, желающие могут потестить сами.
himathparseex.pas.zip
карма: 10
0
файлы: 1himathparseex.pas.zip [8.1KB] [236]
Ответов: 1303
Рейтинг: 405
#10: 2014-06-09 23:59:31 ЛС | профиль | цитата
Assasin, с таким быстродействием компонент станет более популярным. Сейчас использовать стандартный MathParse просто невозможно(это я про своё болото 3d графика)
delphi4.png
[offtop]
трехкратный на FPC 1.9.6.
а пользователи и подумают как плох компилятор FPC , да упокоится он с миром. Жалко что наше сообщество прохладно относится к FPC 2.6.Х, в результате код обростает кучей дефайнов и костылей.[/offtop]


карма: 3

0
файлы: 1delphi4.png [1.1KB] [902]
Ответов: 1376
Рейтинг: 197
#11: 2014-06-10 06:44:34 ЛС | профиль | цитата
Assasin, потестил динамическое изменение MathStr, при пустой строке выдаёт ошибку синтаксиса
code_33773.txt
карма: 1

0
файлы: 1code_33773.txt [801B] [264]
Разработчик
Ответов: 4680
Рейтинг: 423
#12: 2014-06-10 10:15:28 ЛС | профиль | цитата
foksov, вообще в MathParse такая же ошибка. Сейчас компиляция происходит в момент установки MathStr и свойства DebugMode, оба этих свойства устанавливаются в момент запуска программы, отсюда и ошибка. Можно сделать как в FastMathParse - компилировать при первом обращении к doCalc, а потом использовать уже готовое. По идее пустую строку никак не вычислишь, поэтому стоит оставить возникновение такой ошибки, как считаете?
карма: 10
0
Ответов: 1376
Рейтинг: 197
#13: 2014-06-10 10:25:23 ЛС | профиль | цитата
Assasin, у меня в MathParse такой ошибки нет, т.е. с пустой строкой без ошибок запускается в простой схеме, состоящей из формы и компонента MathParse, а вот если установить в схему MathParseEx, то возникает ошибка
Assasin писал(а):
стоит оставить возникновение такой ошибки
тогда в описании надо добавить, что отсутствие мат.строки не допустимо
карма: 1

0
Разработчик
Ответов: 4680
Рейтинг: 423
#14: 2014-06-10 10:40:28 ЛС | профиль | цитата
foksov, при запуске с MathParse с пустой строкой никаких ошибок выдавать не будет, а при doCalc выдаст, я выше и написал, почему так происходит:
Assasin писал(а):
Сейчас компиляция происходит в момент установки MathStr и свойства DebugMode, оба этих свойства устанавливаются в момент запуска программы, отсюда и ошибка.

В MathParse разбор выражения производится каждый раз при вычислении выражения, поэтому ошибка возникнет только в момент doCalc.
карма: 10
0
Ответов: 9906
Рейтинг: 351
#15: 2014-06-10 14:34:18 ЛС | профиль | цитата
Первое
Парни, не торопитесь хвастаться результатами тестов по быстродействию.
ЭКСПЕРИМЕНТ - это Вам не баб щупать... Тут думать надо.
Информация к размышлению: быстродействие элемента состоит из двух (грубо говоря) частей: из "стрельбы" по интерфейсным точкам, и собственно вычислительного процесса.
Ну если второй гораздо больше - тогда ДА. Результатами сразу можно хвастаться.
А вот для FastMathParse (к примеру) - наоборот.
Замахаетесь Вы измерять у него "собственное время". Пока формулу в 1000 символов не напишите (что тоже непросто -- он же гад оптимизирует).

Ну это так - "информация к размышлению"


Assasin писал(а):
Ну это уже утопия
Тогда зачем ты этим занимаешься, спрашивается.
300 строк кода - НЕ УТОПИЯ. Там, через конечное время - не будет "незаметных мелочей".
Ну и так далее... Каждый структурный уровень - ограничивается в размере.
Волевым образом.
Не будешь ограничивать - на всю жизнь твоей религией будет "одна незаметная мелочь сидит и ждет".

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

Да, на сегодня такой технологии фактически не существует. Т.е., термин "инженерное программирование" - есть, а самого Инженерного программирования - нет.
И это не философия, а суровая правда. К сожалению.
Ну и, конечно же, работают пиар техники: создать Технологию гораздо сложнее, чем убедить всех, что "программ без ошибок не бывает".
Бывают.



Ну ладно, вот чего я про все это (MathParseEx) думаю...

Надо отладить этот элемент.
До НУЛЕВОГО количества ошибок
Добавить к нему вычисление константных выражений в Compile-Time
Выкинуть из него суффикс Ex
И жить счастливо.

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


карма: 9

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)