Pull to refresh

Comments 12

Иными словами, вы описали использование замыканий в MATLAB. Наверное, стоило об этом упомянуть в самом начале для большей ясности.
Это ни в коем случае не критика и не придирка :) Просто штука эта достаточно известная, а именно она и раскрывается в статье.
Если для вас это новое, то советую почитать теорию про замыкания, функции высшего порядка и плюшки Lexical Scope — это в ряде случаев мощнейшие инструменты, позволяющие получать простые и красивые решения сложных задач. Думаю, это может помочь в вашей области деятельности.
Это все здорово, но не стоит забывать про высокие накладные расходы при использовании указателей на функции и замыкания в матлабе. Не зная этого, можно долго искать узкое место. Просто для примера попробуйте сравнить вызов в цикле встроенной функции, скажем sin и её же через указатель @sin. Разница будет раз в 20. Могу найти свой старый бенчмарк, в котором оцениваются накладные расходы на вызов функций и методов при разных условиях, в том числе при использовании замыканий. Например, при использовании ООП накладные расходы просто огромны, о чём я писал в комментарии к недавней статье про матлаб.
Да, конечно, накладные расходы высоки. Но задач, когда экономия в разы выше — множество. И не только таких надуманных, как в статье, но и вполне жизненных. В частности, эта статья навеяна рабочей ситуацией — занимались планированием оптимального движения избыточного манипулятора вдоль заданного пути, и я разбирал чужой матлабовский код. За счет введения таких замыканий существенно повысили быстродействие.
А между вызовом встроенной и пользовательской функцией разница заметна? Сейчас проверить не могу, но предпологаю, что пользовательские функции будут проигрывать замыканиям не столь сильно.
Примерно как-то так получается. Функции вызывались 10000 раз в цикле. Это время и замерялось.

По функциям:
0 - вызов функции sin как есть sin(x)
1 - вызов функции sin через указатель @ sin
2 - вызов функции sin через обёртку из анонимной функции @(x) sin(x)
3 - вызов функции sin через обёртку из анонимной и nested функций @(x) sin1(x)
4 - вызов функции sin через обёртку из анонимной и nested функции с передачей параметра, доступного в анонимной функции @(x) sin2(x, p)
5 - вызов функции sin через обёртку из анонимной и nested функции, в которой используется параметр, доступный в nested функции @(x) sin3(x)



Thanks!

Странно, что 1 медленнее чем 2.

То, что 5 так тормозит, неприятно, но будем учитывать.
Странно, что 1 медленнее чем 2.

Это меня тоже сильно удивляет, но факт остаётся фактом: прямой указатель на встроенную функцию гораздо медленнее, чем указатель на обёртку из анонимной функции.
Хм. На моем i7-2600@3.4GHz, 16GB RAM, Matlab R2012a это выполняется почти в 10 раз быстрее. Может, там цикл на 100'000 раз? Кстати, в R2013a еще примерно на 5% быстрее.
Можно посмотреть код sin2 и sin3?
Да, цикл выполнялся 100000, потерялся один нолик.

Код функций простейший:
function y = sin2(x, a)
    y = sin(x);
    a;
end

function y = sin3(x)
     % nested-функция, параметр p определён во внешней функции
     y = sin(x);
     p;
end

Как видно, параметры даже явно не используются, просто присутствуют в теле функции, что значительно замедляет их работу.
Спасибо, прекрасное решение (я тоже не знал слова «замыкание» — спасибо и за него)!
Sign up to leave a comment.

Articles