Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.01.2013, 12:51   #1
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию Оптимизация приложения

Привет форумчанам.
Возникла проблема. Есть приложение, которое строит поверхность уровня. Но оно работает очень долго: 200^3 точек - полторы минуты. Львиную долю времени расчетов занимает расчет значения в точке (через обратную польскую запись).

Я где-то слышал, что если вынести эту функцию в отдельный модуль (unit), то быстродействие увеличится. Так ли это? И есть ли какие-нибудь другие способы ускорить программу?
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 16:10   #2
SoftKoc
Форумчанин
 
Аватар для SoftKoc
 
Регистрация: 07.11.2009
Сообщений: 218
Сообщение

Цитата:
Сообщение от Григоренко Степан Посмотреть сообщение
Привет форумчанам.
Возникла проблема. Есть приложение, которое строит поверхность уровня. Но оно работает очень долго: 200^3 точек - полторы минуты. Львиную долю времени расчетов занимает расчет значения в точке (через обратную польскую запись).

Я где-то слышал, что если вынести эту функцию в отдельный модуль (unit), то быстродействие увеличится. Так ли это? И есть ли какие-нибудь другие способы ускорить программу?
От того что ты вынесешь функцию в другой модуль - точно ничего не измениться.
Ускорить можно методом оптимизации кода.

Выложи исходник и тогда может кто-то чем-то и поможет
Я бы изменил мир, но Бог не дает исходников...
Если помог, нажми на весы и поставь плюс - в знак благодарности
SoftKoc вне форума Ответить с цитированием
Старый 13.01.2013, 20:36   #3
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

Код:
 if F1 then
    begin
      /// //подставляем значения
      for I := 0 to CubeNumberZ - 1 do
        for J := 0 to CubeNumberX - 1 do
          for K := 0 to CubeNumberY - 1 do
          begin

            F1:= true;

            X := Cube[I, J, K].Coord.X;
            Y := Cube[I, J, K].Coord.Y;
            Z := Cube[I, J, K].Coord.Z;

            Tmp.Max := 0;
            SetLength(Bcp.Data, Osn.Max);
            for U := 0 to Osn.Max - 1 do
              Bcp.Data[U] := Osn.Data[U];
            Bcp.Max := Osn.Max;

            while (Bcp.Max > 0) do
            begin
              Pop(Bcp, str);
              if (str[1] in ['0' .. '9', 'x', 'y', 'z', 'p']) or
                ((Length(str) > 1) and (str[2] in ['0' .. '9', 'x', 'y', 'z'])) then
                Push(Tmp, str)
              else
              begin
                Pop(Tmp, strtemp);
                if strtemp[1] in ['x', 'y', 'z'] then
                  case strtemp[1] of
                    'x':
                      a2 := X;
                    'y':
                      a2 := Y;
                    'z':
                      a2 := Z;
                  end
                else
                  a2 := strtofloat(strtemp);

                if str[1] in ['+', '-', '*', '/', '^'] then
                begin
                  Pop(Tmp, strtemp);
                  if strtemp[1] in ['x', 'y', 'z'] then
                    case strtemp[1] of
                      'x':
                        a1 := X;
                      'y':
                        a1 := Y;
                      'z':
                        a1 := Z;
                    end
                  else
                    a1 := strtofloat(strtemp);
                end;
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 20:37   #4
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

Код:
 case str[1] of
                  '+':
                    strtemp := floattostr(a1 + a2);
                  '-':
                    strtemp := floattostr(a1 - a2);
                  '/':
                    if a2 = 0 then
                    begin
                      Cube[I, J, K].IfBound := false;
                      F1 := false;
                      Break;
                    end
                    else
                      strtemp := floattostr(a1 / a2);
                  '*':
                    strtemp := floattostr(a1 * a2);
                  '^':
                    begin
                      if (len(round(a1)) <= 4) and (len(round(a2)) <= 3) then
                      begin
                        if a2 <= 0 then
                          if (a1 <= 0) and (frac(a2) <> 0) then
                          begin
                            Cube[I, J, K].IfBound := false;
                            F1 := false;
                            Break;
                          end
                          else
                            strtemp := floattostr(1 / Power(a1, abs(a2)))
                          else
                            if (a1 <= 0) and (frac(a2) <> 0) then
                            begin
                              Cube[I, J, K].IfBound := false;
                              F1 := false;
                              Break;
                            end
                            else
                              strtemp := floattostr(Power(a1, a2));
                      end
                      else
                      begin
                        Cube[I, J, K].IfBound := false;
                        F1 := false;
                        Break;
                      end;
                    end;
                  '!':
                    begin
                      if (a2 >= 0) and (a2 <= 170) then
                        if a2 = 0 then
                          strtemp := '1'
                        else
                          strtemp := floattostr(sqrt(2 * pi * a2) * Power((a2 / 2.71828), a2))
                          //формула Стирлинга
                        else
                        begin
                          Cube[I, J, K].IfBound := false;
                          F1 := false;
                          Break;
                        end;
                    end;
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 20:37   #5
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

Код:
'c':
                    strtemp := floattostr(cos(a2));
                  's':
                    strtemp := floattostr(sin(a2));
                  't':
                    strtemp := floattostr(tan(a2));
                  'g':
                    if (a2 <> 0) then
                    begin
                      strtemp := floattostr(cot(a2));
                    end
                    else
                    begin
                      Cube[I, J, K].IfBound := false;
                      F1 := false;
                      Break;
                    end;
                  'l':
                    if a2 > 0 then
                    begin
                      strtemp := floattostr(ln(a2));
                    end
                    else
                    begin
                      Cube[I, J, K].IfBound := false;
                      F1 := false;
                      Break;
                    end;
                  'e':
                    strtemp := floattostr(exp(a2));
                  'p':
                    strtemp := floattostr(pi);
                  'a':
                    if (a2 > -1) and (a2 < 1) then
                    begin
                      strtemp := floattostr(arcsin(a2));
                    end
                    else
                    begin
                      Cube[I, J, K].IfBound := false;
                      F1 := false;
                      Break;
                    end;
                  'b':
                    if (a2 > -1) and (a2 < 1) then
                    begin
                      strtemp := floattostr(arccos(a2));
                    end
                    else
                    begin
                      Cube[I, J, K].IfBound := false;
                      F1 := false;
                      Break;
                    end;
                  'w':
                    strtemp := floattostr(arctan(a2));
                  'd':
                    strtemp := floattostr(arccot(a2));
                  'o':
                    strtemp := floattostr(sinh(a2));
                  'k':
                    strtemp := floattostr(cosh(a2));
                  'm':
                    strtemp := floattostr(tanh(a2));
                  'n':
                    strtemp := floattostr(coth(a2));
                  'i':
                    strtemp := floattostr(sign(a2));
                  'u':
                    strtemp := floattostr(abs(a2));
                  'r':
                    begin
                      Randomize;
                      strtemp := floattostr(Random(Trunc(a2)));
                    end;
                end; //case
                Push(Tmp, strtemp);
              end; //begin
            end; //while

            if F1 then
              Cube[I, J, K].Result := strtofloat(Tmp.Data[0])
            else
            begin
              Cube[I, J, K].IfBound:= false;
              Cube[I, J, K].Result := 1E+300;
            end;
          end; //for
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 20:40   #6
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

К сожалению, как короче сделать, не придумал (((
Код:
//стек для обратной польской записи
TStack = record 
  Max: Integer;
  Data: array of String;
End;

Procedure Push(var Stack: TStack; ch: string);
begin
  if Stack.Max = Length(Stack.Data) then
    SetLength(Stack.Data, Stack.Max + 5);
  Stack.Data[Stack.Max] := ch;
  Stack.Max := Stack.Max + 1;
end;

Procedure Pop(var Stack: TStack; Var ch: string);
begin
  if Length(Stack.Data) > 0 then
  begin
    ch := Stack.Data[Stack.Max - 1];
    Stack.Max := Stack.Max - 1;
    if Length(Stack.Data) - Stack.Max > 5 then
      SetLength(Stack.Data, Stack.Max);
  end;
end;
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 20:41   #7
Григоренко Степан
Пользователь
 
Регистрация: 05.05.2011
Сообщений: 35
По умолчанию

В принципе, упростить можно только со сменой основной структуры - сменить case на что-нибудь еще. Но на что?
Григоренко Степан вне форума Ответить с цитированием
Старый 13.01.2013, 23:43   #8
SNUPY
Форумчанин
 
Регистрация: 15.02.2008
Сообщений: 621
По умолчанию

В коде не стал разбираться. Как кардинальное советую применить нити http://www.delphimaster.ru/articles/thread/index.html
Помог? Ну так нажми на весы!
SNUPY вне форума Ответить с цитированием
Старый 14.01.2013, 10:24   #9
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

во первых какая формула? а то малоли километрокая формула
во вторых быстрее "скомпилировать" формулу в некоторый плоский байткод, а не бегать по кейзу каждый раз разбирая формулу

например
Prepare(Math,'x^2-y+z/10');
v:=Value(Math,x,y,z);

где в Math
consts:array of Float;
F:array of operands;
Stack;

и тупо
for i:=0 to length(F)-1 do
DoOper(f[i]);



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

Последний раз редактировалось Slym; 14.01.2013 в 10:37.
Slym вне форума Ответить с цитированием
Старый 14.01.2013, 21:49   #10
SNUPY
Форумчанин
 
Регистрация: 15.02.2008
Сообщений: 621
По умолчанию

если уж говорить о по настоящему кардинальным подходах:
1. сделать как асемблерную вставку
2. OpenCL.

Но как уже было сказано ранее стоит избавиться от ресурсоёмких операций.
Помог? Ну так нажми на весы!
SNUPY вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Автозапуск приложения. Но вопрос совсем не про автозапуск приложения. avd Общие вопросы Delphi 4 30.08.2012 22:24
После запуска приложения из службы созданной на C# не отображается иконка приложения dmail1976 Общие вопросы .NET 1 22.09.2011 13:38
Делаю сайты, пишу маленькие/большие скрипты. Пишу веб-приложения и приложения под Windows. SkyM@n Фриланс 3 29.12.2007 16:21