Почему функция решения Matlab занимает меньше времени после однократного запуска? - PullRequest
1 голос
/ 15 апреля 2019

У меня есть некоторый код Matlab, который вызывает функцию решения некоторых символических ограничений. При первом запуске решение занимает ~ 6 секунд. После первого раза решение занимает ~ 0,3 секунды. Если я изменю входные переменные, на решение снова уходит ~ 6 секунд.

Это потому, что при казнях после первого Matlab вспоминает, что у него был ответ раньше, и просто использует его повторно? Или что-то еще происходит?

Ниже приведен код, демонстрирующий это поведение.

clear; clc

d1 = 25;
d2 = 15;
d3 = 7.5;
d4 = 4.5;

x1 = -0.1521;
y1 = 0.2673;
z1 = 2.3;

x21 = -0.3473;
y21 = 0.3298;

x3 = -0.434;
y3 = 0.2502;
z3 = 2.3;

g = [x1-x3,y1-y3,z1-z3];


syms  X1 Y1 Z1  X2 Y2 Z2  X3 Y3 Z3  X4 Y4 Z4 ...
    x22 y22 z22 t2_2d t1_2d ...
    t1 t2 t3 t4 ...
    real
assumeAlso([Z1 Z2 Z3 Z4 t1 t2 t3],'positive')


constraints = [
        x22 == (t2_2d * (-1/g(1)) ) + x21
        x22 == (t1_2d * g(1)) + x1

        y22 == (t2_2d * (-1/g(2)) ) + y21
        y22 == (t1_2d * g(2)) + y1

        z22 == z1


        X1 == t1*x1
        Y1 == t1*y1
        Z1 == t1*z1

        X2 == t2*x22
        Y2 == t2*y22
        Z2 == t2*z22

        X3 == t3*x3
        Y3 == t3*y3
        Z3 == t3*z3


        (X1-X3)^2 + (Y1-Y3)^2 + (Z1-Z3)^2 == (d1+d2)^2
        (X1-X2)^2 + (Y1-Y2)^2 + (Z1-Z2)^2 == d1^2
        (X2-X3)^2 + (Y2-Y3)^2 + (Z2-Z3)^2 == d2^2


        sum([X4 Y4 Z4] .* cross([X1 Y1 Z1],[X3 Y3 Z3])) == 0
        (X1-X4)^2 + (Y1-Y4)^2 + (Z1-Z4)^2 == (d1+d2+d3)^2 + d4^2
        (X3-X4)^2 + (Y3-Y4)^2 + (Z3-Z4)^2 == d3^2 + d4^2
];

tic
solved = solve(constraints);
toc

tic
solved = solve(constraints);
toc

tic
solved = solve(constraints);
toc

tic
solved = solve(constraints);
toc

Мотивация этого вопроса заключается в том, что я хотел бы запустить решатель как можно быстрее с теми же ограничениями на изменение входных данных. Я надеюсь, что ответ поможет мне найти способ выполнения ~ 0,3 секунды каждый раз вместо ~ 6 секунд.

1 Ответ

1 голос
/ 15 апреля 2019

Я предполагаю, что это потому, что код будет кэшироваться при первом запуске, поэтому последующие запуски будут выполняться быстрее.Изменяя параметры, вы должны выполнить код один раз, чтобы новые определения кэшировались.

MATLAB может кэшировать дескрипторы сценариев с помощью временного каталога.Например, выполните clean all, затем запустите [M,X,C] = inmem('-completenames') до и после запуска сценария.Вы заметите, что были кэшированы следующие классы:

{'matlab.internal.editor.eval.TempFolder'                           }
{'matlab.internal.editor.eval.TmpFilePath'                          }
{'matlab.internal.editor.EODataStore'                               }

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

profile on
solved = solve(constraints);
profile viewer

Затем вы можете увидеть, что происходит внутри mupadengine.evalin, который отвечает за оценку символического выражения..

...