2017-01-25 39 views
2

我的問題:給定一個函數句柄,matlab是否每次需要評估它時都解析字符串,或者只是一次,然後緩存它?Matlab在函數句柄的運行時解析

考慮巧妙的功能

function [] = foo(func) 
for j=1:1e4 
    func(j); 
end 

和腳本

func1 = @(x) 5*abs(x)^2 
function foo(func1); 

在運行時,MATLAB需要解釋@(x) 5*abs(x)^2的功能。在這個例子中,它做了一次,還是一千次?

回答

6

首先@(x)cos(x)不是一個字符串,它是一個anonymous function declaration。當你創建一個匿名函數時,MATLAB本質上創建了一個函數對象,它包含了所有需要運行的信息。這個匿名函數可以傳遞給各種函數,甚至保存到一個文件中。因此,它只被構建一次並進行多次評估。

評估時,MATLAB不會執行任何緩存,因此多次調用具有相同輸入的同一個匿名函數會導致每次都評估匿名函數的內容。

如果你想獲得您的匿名功能,包括函數的局部工作空間的更多信息,你可以使用functions功能

f = @(x)cos(x); 

functions(f) 

%   function: '@(x)cos(x)' 
%    type: 'anonymous' 
%    file: '' 
%   workspace: {[1x1 struct]} 
% within_file_path: '__base_function' 

話雖這麼說,在你的榜樣,它可以真的減少到function handle而不是匿名函數,因爲您將所有輸入參數直接傳遞給cos而不進行修改。正如你所看到的,這具有不同的內部表現形式,而且從一些初步的基準測試來看,它似乎稍快一些。

f = @cos 

functions(f) 

% function: 'cos' 
%  type: 'simple' 
%  file: '' 

和快速基準

function benchit 
    fprintf('Anonymous function: %0.4f\n', timeit(@option1)); 
    fprintf('Function handle: %0.4f\n', timeit(@option2)); 
end 

function option2() 
    f = @(x)cos(x); 
    for k = 1:10000 
     f(k); 
    end 
end 

function option1() 
    f = @cos; 
    for k = 1:10000 
     f(k); 
    end 
end 

而且結果(不是一個真正的巨大差異)

Anonymous function: 0.0056 
Function handle: 0.0049 

一些事情

  • 創建匿名函數時,匿名函數聲明必須仍然遵循MATLAB的所有標準語法規則,否則將不會創建它。例如,下面將匿名函數創建期間拋出一個錯誤,因爲它是無效的語法

    func = @(x)thing] 
    

    Error: Unbalanced or unexpected parenthesis or bracket.

  • 當你評估一個匿名函數(這是成功創建後),它就像評估任何其他功能,因爲匿名函數可能會引發錯誤,錯誤取決於輸入。

    func = @(x) x + [1 2]; 
    
    func([3 4]) 
    % 4 6 
    
    % Now we're going to pass an array that isn't 1 x 2 
    func([5 6 7]) 
    

    Matrix dimensions must agree.
    Error in @(x)x+[1,2]

+2

'functions'進行了說明:[https://www.mathworks.com/help/matlab/ref/functions.html](https://www.mathworks.com/幫助/ matlab/ref/functions.html) - 但它只是建議用於調試。 – horchler

+0

@horchler威爾普,不知道我爲什麼這麼想。更新。謝謝。 – Suever

+0

@Suever謝謝。隨之而來的幾個。 (一)我明白爲什麼餘弦是一個壞榜樣,我會給一個真正需要匿名函數的例子。 (b)創建匿名函數的次數很多,但只有當您嘗試評估或執行它時,它纔會拋出一個無效的異常。嘗試定義'func2 =(x)dfadf9x)'。那麼,它爲'func2'存儲了什麼樣的函數呢? –