Вверх ↑
Этот топик читают: Гость
Ответов: 9906
Рейтинг: 351
#31: 2014-06-17 20:45:52 ЛС | профиль | цитата
Угу. В 14+2*%1 -- не сможет.
В смысле - нафига козе баян... (мы, кстати говоря, обсуждали с Dilma эти вопросы на этапе разработки Fast-а)
А вот в 2*(%1+7) -- сможет. Ничем не хуже, между прочим...

Кстати, Fast тоже скобки не раскрывает.
Есть еще вопросы оптимизации...
Главный - не должно быть динамического выделения памяти в Run-Time.
Никаких аллокаций - и будет всем хорошо
Размер стека можно и при компиляции посчитать.
Да и длину MT-цепочки - тоже можно, наверное.
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#32: 2014-06-17 20:52:43 ЛС | профиль | цитата
Galkov писал(а):
Размер стека можно и при компиляции посчитать.

Оно только при первом вычислении выделяет столько, чтоб точно хватало, а потом использует уже имеющееся. Остается, конечно, небольшой оверхед (только в случае стека - не более 80 байт), если критично, можно и подсчитывать при компиляции, конечно.
Galkov писал(а):
Да и длину MT-цепочки - тоже можно, наверное.

А вот это кстати классный вариант, достойное предложение.
Galkov писал(а):
А в 2*(%1+7) -- сможет

Не, не сможет. Аргументы рассматриваются последовательно, и при первом встречном %n сразу будет "это не константа, значит пишем в программу".
карма: 10
0
Ответов: 9906
Рейтинг: 351
#33: 2014-06-17 20:53:39 ЛС | профиль | цитата
А я говорю - сможет
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#34: 2014-06-17 20:54:13 ЛС | профиль | цитата
Galkov писал(а):
А я говорю - сможет

Все понятно, значит мне придется научить алгоритм смочь
карма: 10
0
Ответов: 8921
Рейтинг: 823
#35: 2014-06-17 22:13:10 ЛС | профиль | цитата
Galkov, в алгебре (геометрии) много разных возможных сокращений, все-то их нет смысла учитывать или есть? Да и одно дело когда вычисление единственное, а другое в цикле 1000000. (Но вдруг в формуле что-то подобное (sin(%1))^2 + (cos(%1))^2, как не заменить на "+1" )
карма: 19

0
Ответов: 9906
Рейтинг: 351
#36: 2014-06-19 09:15:20 ЛС | профиль | цитата
Есть (точнее, было выработано при вышеупомянутом обсуждении с Dilma) очень практическое соображение: "А ну его нафиг!!!"

Не надо быть святее Папы Римского.
Ну типа помочь пользователю - это одно. А думать за него - это другое.
Скажем, корни фильтра Баттерворта равномерно расположены на круге. Коэффициенты фильтрации, соответственно, определяются косинусами каких-то очень простых константных выражений.
Посчитать их в Compile-Time - это помощь.

А думать за кого-то (раскрывать скобки, выделять общие подвыражения) -- бесперспективное занятие.
Тут два философских варианта:
   Либо - все равно не поможет (вариант тупого юзера).
   Либо - не факт, что ты умнее Автора (вариант умного юзера).
------------ Дoбавленo в 08.21:


2Assasin,
1) Варнинг на 557-й можно убрать примерно так:
#pas
else{CmdXor:} b := (x1 <> 0) xor (x2 <> 0);
2) Варнинг на 1355-й... Да перенеси ты cnt := 0;, вообще, выше CASE. Хай гнида подавится...

3) Внимание, 1334: 26, 30:, это вам не 26..30:. Тем более, что при "вычислении" - второй вариант остался

------------ Дoбавленo в 09.15:
А вообще-то, функции min/max с одним аргументом -- смотрятся немного странно. Хотя и работают.
Предлагаю сделать "вклейку":
#pas
......
31, 32:
begin
if Token<>',' then
{$ifdef F_P} begin Err:=0; exit; end;
{$else} raise Exception.Create(e_Custom,''); {$endif}
while Token=',' do begin
GetToken; Level1a; {$ifdef F_P} if Err>=0 then exit; {$endif}
inc(cnt);
end;
end;
......
И после этого, заменить кошмарное условие:
#pas
if (i = 31) or (i = 32) then begin
FProgram.WriteInteger(cnt);
end;
на более простое:
#pas
if (cnt>0) then FProgram.WriteInteger(cnt);
карма: 9

1
Голосовали:Леонид
Разработчик
Ответов: 4698
Рейтинг: 426
#37: 2014-06-22 22:11:18 ЛС | профиль | цитата
Galkov, подскажи пожалуйста, а каким образом была решена проблема преждевременного добавления операционных кодов? Например, есть выражение 2/(2+%1). Пусть %1 = 2 (компилятор об этом не знает). Очевидно, что результат = 0.5. Если не возвращать из каждой функции levelX структуру, в которой хранится либо промежуточный код, либо константа, (потому что это вариант, требующий значительной переделки алгоритма компиляции) то получается такая последовательность действий компилятора:
1. Получаем число 2 в функции оператора /
2. Входим в скобки.
3. Получаем число 2 в функции оператора +
4. Получаем переменную %1.
5. Функция оператора + видит, что выражение не вычислить на месте и последовательно пишет в код 2, %1 и операцию сложения.
6. Выходим из скобок.
7. Функция оператора / видит, что выражение в скобках не вычислилось на месте, и пишет свой аргумент в код, затем операцию деления.
Итого, получим такую цепочку: 2, %1, +, 2, /. Выполнив ее, получаем (2+2)/2 = 2.
Как решена такая проблема в FastMathParse?
карма: 10
0
Ответов: 9906
Рейтинг: 351
#38: 2014-06-23 11:18:32 ЛС | профиль | цитата
В FastMathParse проблема сия решалась кошмарным образом.
Как позже оказалось.
Не, когда планировалось - все казалось не очень сложным...

Выполнение последнего действия откладывалось "на потом". Поэтому результатом разбора "была как бы формула" с одним оператором. И, соответственно, указывались типы аргументов. Аргументы могли быть: константа (она и указывалась), данные в памяти (указывался адрес, определяемый при компиляции), данные в стеке сопроцессора (которые являлись результатом вычисления, и именно для них имелся код).

Какие тут возникали проблемы ...

Самая первая, философская. Никаких внешних функций/подпрограмм вызвать нельзя, без полного сброса стека сопроцессора. Как бы, каждый программный модуль имеет права на ВЕСЬ стек сопроцессора (не такой уж и глубокий - 16, кажется). Поэтому сразу идут лесом всякие массивы, матрицы, функции... А внешние данные/аргументы читаются только один раз, перед вычислением. А компилятор таки смекает (в смысле - флажки расставляет), какие надо читать, а какие - нет. Получается, что они все, как бы сразу -- в кэше.

Вторая проблема - конечный стек сопроцессора, а пользователя в длине формулы мы не ограничиваем. Возни на эту тему тоже хватало.

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

И для меня, если честно, в случае необходимости внесения существенных изменений (например, арктангенсы какие нибудь) в FastMathParse -- нужно не менее недели, чтобы разобраться со своим же кодом...
При этом, зная общую философию. Которую я излагал сейчас исключительно по памяти, не глядя в коды.


Вот

И, чего-то мне думается, что в случае MathParseEx - то же самое можно (и нужно) сделать гораздо проще.
Сам тот факт, что две первые вышеуказанные проблемы начисто отсутствуют - достойная причина для самого MathParseEx.
Как бы "переносимость" - немножко за уши притянуто. А вот отсутствие проблем масштабирования - аргумент объективный.

Мысли о реализации вышеупомянутого безобразия - есть у меня...
Расскажу о них. Через часик (перекур надо сделать)



------------ Дoбавленo в 10.17:
Значит так... Мысль примерно такая:
Assasin писал(а):
(потому что это вариант, требующий значительной переделки алгоритма компиляции)

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

Например, объявим:
#pas
type Titem = record adrConst:pchar; adrCmd:pchar; stackSize:integer; {может и еще чего потом придумается} end;
...
procedure Level0 (var item:Titem);
procedure Level1a(var item:Titem);
procedure Level1b(var item:Titem);
...
Как бы ничего особенного, пока мы не начинаем анализировать значение полей.
Вряд ли, это пока серьезные переделки. Грубо говоря, пока вообще никаких.

Вот, а теперь -- чего мы себе думаем про смысл этих полей...
А мы себе думаем, что код у нас ровно тот, что и сейчас, но если он получен с помощью константы, тогда первый адрес указывает на то место в "программе", где стоит CmdPush, а второй - на место, где этот "CmdPush" реализован. На последнюю команду, типа CmdAdd, в общем.
Код боевой, ничего "на потом" не отложено, его можно запускать, не обращая внимание ни на что.
А вот теперь, предположим, мы хотим прибавить еще константу.
Если у нас первый адрес не нулевой, а по второму адресу стоит CmdAdd, то кто нам мешает прибавить эту константу, в Compile-Time, по адресу после CmdPush.
Вроде бы никто. И это есть хорошо.

В чем мысль состоит то:
Занимаемся мы сложением в Level1b, скажем для формулы: (1 + %2 + (%1 - 2))/2
1) Получаем первым операндом {<адрес для CmdPush[1]>, nil, ... }. Это мы хотим, чтобы level6 именно так отреагировал на TokNumber. Почему бы и нет...
2) Получаем второй операнд (совместно с информацией о именно сложении) как {nil, <адрес для CmdRead>, ... }
3) Как и сейчас, притуляем в зад команду CmdAdd. Фиксируем в item адрес первой "константы", и адрес свежепритуленной команды. Кодинг пока, ровно тот же, что и сейчас.
4) Получаем третий операнд (совместно с информацией о именно сложении) как {<адрес для CmdPush[-2]>, <адрес для CmdAdd>, ... }
5) Если игнорировать содержимое tmpItem (это не наш аргумент, а локальная переменная, для возврата из других levelXXX), то ничего не остается, как притулить в зад CmdAdd. Что сегодня мы и делаем. А если подумать над содержимым tmpItem, то мы можем прибавить (-2) к ранее зафиксированной константе в item (по п.3 - и там получится -1), удалить из программы к чертовой матери CmdPush и CmdAdd для третьего опреранда. Ну и, естественно, притулить в зад свой собственный CmdAdd.
....
Как бы получается, что мы создаем программу, как и раньше. НО, иногда, вырезаем из нее лишнее (этого метода еще нет в TProgram), и модифицируем константы (как бы это и есть вычисления в Compile-Time), туда уже зашитые.

Подчеркну, это пока еще не опробованная мысль. Возможны некоторые "пеньки" по дороге.
Но, попробовать стоит.... Мне кажется.



------------ Дoбавленo в 11.18:
Да, я как бы по умолчанию предполагал, что сегодняшняя реализация TProgram - это уже за пределами добра и зла
С точки зрения эффективности, конечно

Надо делать примерно так:

#pas
type
PReal = ^real;
PInteger = ^integer;
....
THIMathParseEx = class(TDebug)
....
FPgm: array of byte;
Fpc: ^byte; // обычно PC - это Program Counter
FStack: array of real;
Fsp: Preal; // обычно SP - это Stack Pointer
.....

.....
.....

// в качестве примера для ExecuteExpressionPart
while true do begin
cmd := Fpc^; inc(Fpc);
if cmd=CmdEnd then exit; // конец программы
case cmd of
CmdPush: // [val:real] просто число
begin
inc(Fsp); // Обычно (но - обсуждаемо), стек указывает на последнее записанное число
Fsp^ := PReal(Fpc)^;
inc(Fpc,sizeof(real));
end;
CmdAdd, CmdSub, CmdMul, CmdDiv, CmdPow, CmdIDiv, CmdIMod:
begin
x2 := Fsp^; dec(Fsp);
case cmd of
CmdAdd: Fsp^ := Fsp^ + x2;
CmdSub: Fsp^ := Fsp^ - x2;
CmdMul: Fsp^ := Fsp^ * x2;
// Далее: про FPC пока не напрягаюсь, ибо это демка
CmdDiv: Fsp^ := Fsp^ / x2;
CmdIDiv: Fsp^ := Round(Fsp^) div Round(x2);
CmdIMod: Fsp^ := Round(Fsp^) mod Round(x2);
else Power(Fsp^, x2); // Это CmdPow (ибо он последний)
end;
end;
.....
.....
.....

Не думаю, что этот код настолько уж сложно прочитать Человеку Разумному.
НО, использовать два функциональных вызова, плюс мухобойный Move, чтобы прочитать в Run-Time всего ОДЫН байт -- это же полный беспредел
карма: 9

1
Голосовали:Assasin
Разработчик
Ответов: 4698
Рейтинг: 426
#39: 2014-06-23 21:26:51 ЛС | профиль | цитата
Galkov, мне кажется, что выжимать максимум производительности из MathParseEx не стоит, все же когда нужен максимум, тогда уже есть готовый FastMathParse (если, конечно, не зайдет речь о замене FastMathParse на MathParseEx). Поэтому склоняюсь к текущему варианту, где программа и стек реализованы отдельными классами. Фактически, если я буду переписывать классы на переменные и ручную работу с ними, то я начну заниматься микрооптимизациями, которые на практике вообще за меня будет решать компилятор (заинлайниванием вызовов функций).
А вот расширить классы для оптимизации отдельных операций (например, не гонять переменную со стека и обратно) - это можно.
Galkov писал(а):
НО, использовать два функциональных вызова, плюс мухобойный Move, чтобы прочитать в Run-Time всего ОДЫН байт -- это же полный беспредел

Это, пожалуй, верная мысль Read/WriteBinary оставить на случай строк, а остальные R/W переписать на прямую работу с указателями на конкретные значения. И тогда Move не потребуется.
По поводу алгоритма - так до конца и не получилось понять, где мы резервируем, где режем лишнее, поэтому пришла следующая мысль: если операнду слева пришла константа, то он сразу резервирует в программе место под CmdPush, а потом, в конце, когда уже понятно, константное ли выражение, либо оставлять все, как есть (код записан в TProgram правильно), либо смещать позицию в программе обратно, тем самым как бы стирая CmdPush (и следующей записью перезаписывая его окончательно).
карма: 10
0
Ответов: 9906
Рейтинг: 351
#40: 2014-06-24 19:18:26 ЛС | профиль | цитата
Философия - чуток по позже (ясный перец, что твоя - неправильная )

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


НО, почувствуйте разницу
Хотя все почти то же самое...
------------ Дoбавленo в 14.41:
Кстати говоря, перед тестированием на скорость -- снимите DebugMode
((мать его за ногу ))
------------ Дoбавленo в 19.18:
У мине получилось собственное время ~5 раз быстрее (в смысле - меньше), в сравнении тем, чего було
Не путать с тупым измерением полного времени
Собственно, измерения проводились по этой схеме (пост на предыдущей странице в конце)

карма: 9

0
файлы: 1himathparse_qu.rar [8KB] [502]
Разработчик
Ответов: 4698
Рейтинг: 426
#41: 2014-06-25 00:01:01 ЛС | профиль | цитата
Уменьшил собственное время в два раза, убрав использование Move для типов byte, integer, real. Теперь уберу гонение переменной из стека и обратно и продолжу тесты
карма: 10
0
Ответов: 9906
Рейтинг: 351
#42: 2014-06-25 12:25:42 ЛС | профиль | цитата
Про философию

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

Первая культура давно существовала, когда еще и компьютеров не было.
Существуют некие цеховые правила, паттерны разработки, наконец. Опробованные веками.

Зато именно вторая считает себя носителем Истины, закручивая пальцы веером.
По смыслу - IT должна бы быть инженерной культурой. И, может быть, когда нибудь ей и станет.
Когда образованность ее носителей поднимется до уровня, позволяющего познакомиться с опытом предков.

А вот тебе пример из нашего случая (применение философии на практике)
Ну показал же я тебе
#pas
CmdPush: // [val:real] просто число
begin
inc(Fsp);
Fsp^ := PReal(Fpc)^;
inc(Fpc,sizeof(real));
end;
Можно ли сделать лучше? Можно - это идеология Fast-а. Но я знаю чего он стоит, и ограничения им вносимые. Т.е., у меня есть некие доказательства, что надо делать хуже
А оставаясь к концепции интерпретатора? Мне кажется, что нет. Но предложения принимаются.
А может у кого есть иная оригинальная концепция?

И поскольку я Инженер, а не IT-шник, то спрашиваю: Где доказательства, что надо делать ХУЖЕ (оборачивать это дело всякими там классами-дурасами)
И вовсе НЕ СОБИРАЮСЬ доказывать, что надо делать лучше (эффективнее). А просто делаю.
Где та Великая Причина, заставляющая писать на 200 строк кода больше, и терять в эффективности. Мало или много - даже считать не буду, потому что все равно терять.
Где та Великая Причина, заставляющая меня (Читателя) ломать башку над использованием какого-нибудь FAlloced.

Вопросы были риторические. Просто знаю, как обычно IT-народ отвечает: звучат религиозные лозунги, никакой связи не имеющие с поставленной целью.

И вообще, парадигма работы Инженера предполагает обсуждение этих вопросов (размышление над этими вопросами) ДО кодинга, а не ПОСЛЕ.
Сочиняется (придумывается) несколько вариантов развития. Несколько - это обязательно. Выбирается оптимальный по вышеозначенным критериям.
И получается быстрее и эффективнее.

Чего делают программисты, спрашивается.
Они придумывают какой-то один вариант. Жутко гордятся, что они его придумали - работает же!
Потом начинают профилировать. Где-то чего-то исправлять. Отлаживать. Ловить свежевнесенные баги в течении многих лет.
И получается, что высококвалифицированный (!!!) программист больше 10000 строк кода за год написать не может. Обычно - не больше 3000.

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


Я понятно объясняю





------------ Дoбавленo в 12.25:
Про конкретику: теперь буду "цепляться за фразы"
Assasin писал(а):
Galkov, мне кажется, что выжимать максимум производительности из MathParseEx не стоит, все же когда нужен максимум, тогда уже есть готовый FastMathParse

Не надо выжимать. Выжимать - это и есть FastMathParse. И у него есть ограничения в функциональности.
Надо просто не делать глупости. Это не трудно. Разве я этого тебе не показал

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

Ага, ЩАЗ. Разогнался и подпрыгнул.
Потом догнал, и еще раз соптимизировал.
Вообще-то, я коды смотрел (в дизасме)

Assasin писал(а):
А вот расширить классы для оптимизации отдельных операций (например, не гонять переменную со стека и обратно) - это можно

А еще можно не создавать себе проблему, и не придется ее решать.
Assasin, еще один принцип Инженера: он работает не только для компьютера, но и для своего Коллеги. И второе, обычно более важно, чем просто "работает же"
В этом коде:
#pas
x2 := Fsp^; dec(Fsp);
Fsp^ := Fsp^ + x2;
-- мне, Читателю, ясно все. Это постфиксное сложение, а Fsp - указатель на стек. И больше НИЧЕГО. Гарантия отсутствия подводных камней - полная.Второе, значительно более важно, чем понты про (не побоюсь этого слова) -- инкапсуляцию.
А вот если ты "расширишь классы для оптимизации отдельных операций", то полазить по файлу - очень даже придется. Может и не один раз. А может там и ашипка закрадется.
Причем, я сначала буду полдня думать (может это я дурак), перед коллективной разборкой.
И всего этого могло не быть.

Assasin писал(а):
По поводу алгоритма - так до конца и не получилось понять, где мы резервируем, где режем лишнее

Давай тогда говорить на языке знакомых букв и цифр...
А вот твой же Dump для вышеупомянутой формулы (меня задрал CmdDbgLine, и я его заблокировал)
(1 + %2 + (%1 - 2))/2

     Program: 
1 push 1
2 read 1
3 add
4 read 0
5 push 2
6 sub
7 add
8 push 2
9 div
10 end
-- узнаешь брата Колю
Вот, возвращаемся к Level1b (копировать не буду - смотри в код сам)
Чего получается после первого вызова Level2 ???
Это первая строка в дампе (push 1). И мы как-то там, через еще недодуманную структуру Titem должны получить реальный адрес (скорее - индекс в массиве) этих 9-ти байт

Дальше, следующий вызов Level2 добавляет нам вторую строку (read 1). И мы сами добавлям третью (add).
Спрашивается, чего дает третий вызов Level2 ???
Он дает сразу три строки - 4-ю, 5-ю, и 6-ю.
Вот, и мы себе думаем (точнее, пытаемся придумать), что при этом вернутся два адреса (или индекса) в переменной tmp (см. код). Первый показывает (в нашем случае) на 9 байт для 5-й строки (push 2), а второй - на 1 байт команды (в нашем случае) в 6-й строке (sub).

Каков должен быть наш план в этом случае. Чтобы вернуть то, что мы потребовали (его же вернул такой же Level1b, но на более глубоком уровне рекурсии).
Мы должны в аргумент item (см. код) занести адрес первой встреченной константы (в нашем случае это строка 1) и первого оператора, к ней примененного (в нашем случае это строка 3)

ТОДЫ
Отнимаем (ибо sub, а в формуле при этом стоит +) от константы, зафиксированной уже в item - двоечку (ибо push 2).
Удаляем строки 5 и 6 (на самом деле, полученные в tmp после 3-его Level2).
Должны получить:
Так КУ, или не КУ ???

     Program: 
1 push -1
2 read 1
3 add
4 read 0
5 add
6 push 2
7 div
8 end

Повторюсь, пока это "мысли вслух"
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#43: 2014-06-25 12:42:29 ЛС | профиль | цитата
Хм, Galkov, не поверишь, но вот делая себе классы, я как раз считаю, что делаю лучше, и что избавляюсь от проблем, которые возникнут. И я не нахожу пока причин делать хуже (т.е. избавиться от классов и перейти к прямой работе с памятью). Я еще не инженер, конечно, и к концу обучения в универе мои взгляды на программирование могут поменяться ближе к твоей позиции, но на данный момент взгляды те, которые я выше озвучил.
У меня кстати часто наоборот проблема, что я не могу начать писать код, потому что слишком занят решением проблем на этапе проектирования.
карма: 10
0
Ответов: 9906
Рейтинг: 351
#44: 2014-06-25 13:17:10 ЛС | профиль | цитата
Assasin писал(а):
Galkov, не поверишь, но вот делая себе классы, я как раз считаю, что делаю лучше, и что избавляюсь от проблем, которые возникнут.

Поверю. Вас так учат (ничего личного -- это я по своим коллегам сужу)
Не избавляешься от проблем, а их закапываешь в реализации класса.
НО делаешь более удобным их исправление. Ты эти проблемы запланировал.
Затрудняешь чтение, создавая новые логические абстракции.
Сказано: не создавай новые сущности без необходимости ((с)Окамм - вспомни сколь веков назад он жил)

Вот я тебе только что показал 2 строки кода. Где эта необходимость для создания новой сущности
А нет ее. Придумана.

Кстати, ты ничего не сказал про FAlloced.
Вот открой народу глаза, чего это за сепулька, и нафига она нужна.
Прикинь, моего образования не хватило для понимания этой "абстракции"


------------ Дoбавленo в 13.17:
Assasin писал(а):
Я еще не инженер

Ты, главное, сильно не расстраивайся.
С вероятностью 99%, ваши преподы - тоже об этом имеют весьма слабое представление.
Беседовал тут я со своими знакомыми (преподы с ФИТ в НГУ).
По сайтам апологетов "инженерного программирования" полазил....

Ужасть
карма: 9

0
Разработчик
Ответов: 4698
Рейтинг: 426
#45: 2014-06-25 13:32:33 ЛС | профиль | цитата
Galkov писал(а):
Вот я тебе только что показал 2 строки кода. Где эта необходимость для создания новой сущности
А нет ее. Придумана.

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


Возвращаясь к нашим баранам: если разница между классовым подходом и прямым в реализации интерпретации байткода окажется существенной (в 1.5-2 раза), то тогда я приму твою идею, т.к. тогда я увижу доказательства того, что эти меры реально делают лучше. За рекомендации в любом случае спасибо, как известно, годы не проходят просто так, рано или поздно всякий совет пригодится. Я чувствую, что еще не раз вспомню все, что ты мне тут писал. Поэтому еще раз спасибо
------------ Дoбавленo в 13.32:
Galkov писал(а):
Кстати, ты ничего не сказал про FAlloced.
Вот открой народу глаза, чего это за сепулька, и нафига она нужна.

Для того, чтобы хранить размер реально выделенной под поток байт памяти. Использоваться может меньше, а выделяться больше. Это чтобы меньше использовать динамическое выделение.
карма: 10
0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)