В моем коде я должен передать функции несколько больших массивов, и, чтобы упростить читаемость, я использую структуру и называю ее params. Конкретно:
params.grid1 = grid1;
params.grid2 = grid2; % these are big arrays
% etc.
% Define x
y = myfun(x,params)
function y = myfun(x,params)
y = x+params.grid2;
end
Однако я заметил, что следующий код ниже работает намного быстрее:
params.grid1 = grid1;
params.grid2 = grid2; % these are big arrays
% etc.
% Define x
y = x+params.grid2;
Похоже, что вызов функции в первой версии кода существенно снижает производительность. К сожалению, для моего проекта я не могу избежать использования функций (иначе был бы беспорядок). Я думал, что передача структур в функцию - это быстрый вариант. Есть предложения о том, как улучшить скорость?
ЗДЕСЬ MWE:
%% Passing matlab structures to function seems to be slow
clear;clc;close all
n = 100000;
rng('default')
grid1 = rand(n,1);
grid2 = rand(n,1);
params.grid1 = grid1;
params.grid2 = grid2; % these are big arrays
% etc.
% Define x
%% disp('Testing code 1 - passing struct to a function')
tic
x = 3;
[y1,y2] = myfun(x,params);
y1
y2
toc
%% disp('Testing code 2 - no function')
tic
x = 3;
y1 = mean(x+(params.grid1).^2);
y2 = mean(x+(params.grid2).^2);
y1
y2
toc
Для его запуска вам также понадобится следующая функция:
function [y1,y2] = myfun(x,params)
y1 = mean(x+(params.grid1).^2);
y2 = mean(x+(params.grid2).^2);
end
Код 1 (передача структуры функции): Прошедшее время составляет 0,001682 секунды. Код 2 (без передачи структуры в функцию): Прошедшее время составляет 0,000737 секунд.
Перед тестированием я пару раз запускал код, как было предложено.
Чтобы измерить скорость, я использовал tic toc
Пожалуйста, покажите нам минимальный воспроизводимый пример
Привет, Алессандро, если каждая из ваших сеток имеет одинаковый размер, вы можете создать матрицу размерности n + 1 (где n - размер ваших сеток)
Для измерения скорости не используйте tic, toc. Это очень неточно и может ввести в заблуждение. Всегда вставляйте код для синхронизации в функцию (чтобы JIT могла делать свое дело) и используйте timeit для определения времени выполнения функции. timeit будет запускать функцию несколько раз, причем время компиляции не влияет на время.
В частности, при первом вызове функции она будет загружена и скомпилирована, что приведет к сокращению времени. Во второй раз функция будет вызвана намного быстрее. Так что, по крайней мере, запустите функцию один раз, прежде чем синхронизировать ее с вашей конструкцией tic / toc.
@AnderBiguri Я включил MWE
@CrisLuengo Я знаю о JIT, действительно, прежде чем регистрировать время выполнения, я запускал код пару раз, чтобы разрешить предварительную компиляцию. Не могли бы вы предложить, как использовать timeit в моем коде выше (см. Новую версию с mwe)?
Создайте M-файл функции с двумя частными функциями: method1 и method2. Они оба должны принимать массивы x и params и возвращать массивы y1 и y2. В основной функции делаем timeit(@()method1(x,params)) и timeit(@()method2(x,params)). Это даст вам хорошее представление о накладных расходах на вызов функции.
Вы можете добавить в свой тест третью функцию, чтобы увидеть, действительно ли myfun(x,params) медленнее, чем myfun(x,grid1,grid2).





Если вам действительно нужна скорость, избегайте построек. Кроме того, можете ли вы сделать минимальный воспроизводимый пример, который показывает такое поведение? Как вы измерили скорость?