2013-09-23 26 views
5

Я записал функцию в 4 разных способах, и я хочу, чтобы это время.код времени в matlab

Up к теперь я делал это дело:

tic 
%//function 1 
toc 

tic 
%//function 2 
toc 

tic 
%//function 3 
toc 

tic 
%//function 4 
toc 

Но теперь я хочу, чтобы вычислить данные синхронизации для каждой функции для (скажем, в 100 раз) каждый, а затем вычислить среднее время, затраченное на каждый функция. Как я могу это сделать?

Кроме того, я где-то читал, что напечатанное время - это прошедшее время «настенных часов», поэтому оно будет зависеть от того, что делает мой компьютер, пока работает программа MATLAB.

Так есть лучший способ сделать это ?? Я слышал, что есть MATLAB, встроенный в код-профилировщик с командой «profile on». Можете ли вы предложить мне способ, которым я могу его использовать?

Я также проконсультировался по сайтам: Timing code in MATLAB и Profiler to find code bottlenecks.

Пожалуйста, предложите, как это сделать много раз в цикле. Заранее спасибо.

EDIT: 23 сентября 2013: Соблюдая предложения всеобщего я это сделал: Мои функции определяются как один, два, три & четыре.

function [] = one(x) 
I = imread('coins.png'); 
I = double(I); 
I = imresize(I,[x x]); 
sig=.8; % scale parameter in Gaussian kernel 
G=fspecial('gaussian',15,sig); % Caussian kernel 
Img_smooth=conv2(I,G,'same'); % smooth image by Gaussiin convolution 
[Ix,Iy]=gradient(Img_smooth); 
f=Ix.^2+Iy.^2; 
g=1./(1+f); % edge indicator function. 
end 

function [] = two(x) 
I = imread('coins.png'); 
I = double(I); 
I = imresize(I,[x x]); 
sig=.8; % scale parameter in Gaussian kernel 
G=fspecial('gaussian',15,sig); % Caussian kernel 
Img_smooth=imfilter(I,G,'conv'); % smooth image by Gaussiin convolution 
[Ix,Iy]=gradient(Img_smooth); 
f=Ix.^2+Iy.^2; 
g=1./(1+f); % edge indicator function. 
end 

function [] = three(x) 
I = imread('coins.png'); 
I = double(I); 
I = imresize(I,[x x]); 
sig=.8; % scale parameter in Gaussian kernel 
G=fspecial('gaussian',15,sig); % Caussian kernel 
%//Trying to use 1D convolution instead of using 2D convolution 
[U,S,V] = svd(G); 
K1 = U(:,1) * sqrt(S(1,1)); 
K2 = V(:,1)' * sqrt(S(1,1)); 
KI1 = imfilter(I,K1,'conv');        
Img_smooth = imfilter(KI1,K2,'conv'); % smooth image by Gaussiin convolution 
[Ix,Iy]=gradient(Img_smooth); 
f=Ix.^2+Iy.^2; 
g=1./(1+f); % edge indicator function. 
end 

function [] = four(x) 
I = imread('coins.png'); 
I = double(I); 
I = imresize(I,[x x]); 
sig=.8; % scale parameter in Gaussian kernel 
G=fspecial('gaussian',15,sig); % Caussian kernel 
%//Trying to use 1D convolution instead of using 2D convolution 
[U,S,V] = svd(G); 
K1 = U(:,1) * sqrt(S(1,1)); 
K2 = V(:,1)' * sqrt(S(1,1)); 
KI1 = imfilter(I,K1,'conv');        
Img_smooth=conv2(K1,K2,I,'same'); % smooth image by Gaussiin convolution 
[Ix,Iy]=gradient(Img_smooth); 
f=Ix.^2+Iy.^2; 
g=1./(1+f); % edge indicator function. 
end 

Затем я запустил эту программу и получил этот раз:

clc;clear all;close all; 
x=64;N=100; 
tic 
for i=1:N 
    one(x); 
end 
toc 

tic 
for i=1:N 
    two(x); 
end 
toc 

tic 
for i=1:N 
    three(x); 
end 
toc 

tic 
for i=1:N 
    four(x); 
end 
toc 

раз я получил являются:

%//x=64;N=100; 
Elapsed time is 0.898583 seconds. 
Elapsed time is 0.983132 seconds. 
Elapsed time is 0.921140 seconds. 
Elapsed time is 0.811144 seconds. 

%//x=128;N=100; 
Elapsed time is 0.990136 seconds. 
Elapsed time is 1.044167 seconds. 
Elapsed time is 0.999153 seconds. 
Elapsed time is 1.005903 seconds. 

%//x=256;N=100 
Elapsed time is 1.495068 seconds. 
Elapsed time is 1.416523 seconds. 
Elapsed time is 1.462653 seconds. 
Elapsed time is 1.605767 seconds. 

%//x=1024;N=100 
Elapsed time is 16.681720 seconds. 
Elapsed time is 14.857957 seconds. 
Elapsed time is 15.580161 seconds. 
Elapsed time is 19.140707 seconds. 

Является ли мой код времени не так? Я имею в виду технически, я должен получать самые быстрые времена для функции три & четыре всегда. Для разных значений х я получаю разные результаты.

Пожалуйста, ребята, вы могли бы предложить мне лучший подход к измерению времени? Спасибо заранее!

+1

Если вы обеспокоены (короткими) процессами, мешающими вашим результатам измерений. В целом неплохо смотреть на медиану таймингов, а не на среднее. –

ответ

13

Лучший способ ко времени использования кода MATLAB - использовать timeit, доступный с центрального файла обмена файлами MATLAB.

Он был реализован Стивом Эддином, одним из старших разработчиков MathWorks, и он заботится о множестве тонкостей в определении времени вашего кода. Например, код работает очень по-разному, когда он выполняется внутри функции, а не внутри скрипта, и для ее правильного использования JIT-компилятор должен иметь пару «разминки». Он также будет запускать код много раз в цикле и принимать медианную информацию.

Эти вещи трудно получить права, не зная достаточно много о том, как MATLAB работает под капотом, и timeit берет на себя эти вещи для вас - простые приложения tic и toc нет.

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

Обратите внимание, что в последней версии (R2013b) timeit доступен как часть основного MATLAB, и его не нужно получать из Файлового обмена.

Например, для расчета времени функции one с входным аргументом x, равного 64, введите:

myfun = @()one(64); 
timeit(myfun); 

Что это делает, чтобы сделать функции обрабатывать вашей функции one (что делает убедитесь, что код выполнен внутри функции, как указано выше), затем передает этот дескриптор функции в timeit. Результат - timeit - оценка времени, затраченного на выполнение кода.

+1

PS Я только что просмотрел ваш редактирование, содержащее функции 'one',' two' и т. д. Если позже, когда вы собираетесь использовать эти функции, вам потребуются некоторые из их выходов, вы должны действительно вернуть им возвращаемые выходные аргументы. –

+0

Все мои функции возвращают одни и те же выходы. Нужно ли мне время выполнять мои функции с возвратом выходов? Будут ли они тогда показывать differeces? – roni

+1

Если все они возвращают одни и те же выходные аргументы, это, вероятно, не будет существенно влиять на относительные тайминги - это должно иметь одинаковый эффект для каждого. Но, как правило, старайтесь делать то же самое, что они будут фактически использованы, поскольку неясно, какие вещи будут узкими местами. –

1

Использование профилировщика почти так же просто, как крестики/TOC:

profile on; 
for i=1:N 
    your_function() 
end 
profile viewer; 

Если 4 функции являются независимыми и не влияют друг на друга, вы можете также профилирование всех из них в одном блоке:

profile on; 
for i=1:N 
    your_function1() 
    your_function2() 
    your_function3() 
    your_function4() 
end 
profile viewer; 

Профилировщик позволит вам посмотреть время обработки для каждой отдельной строки кода. Вы можете либо установить часы на стене, либо время процессора, значение по умолчанию - cpu-time. См. Документацию profile о том, как ее изменить.

EDIT: Что мне нравится в профилировщике, так это то, что он дает вам разбивку времени обработки каждой подфункции - следовательно, это отличный способ определить узкие места в более крупных процессах. Скорее всего, это не так.

+2

Одна проблема с профилировщиком заключается в том, что он выключает ускоритель JIT. – StrongBad

+0

@ DanielE.Shub Да, спасибо! Сэм тоже объяснил это мне в своем посте! Так лучше или тик-ток? И дайте свои команды относительно etime? – roni

+2

@roni Вам не понадобится 'etime' для выбора времени. В лучшем случае это может дать вам те же результаты, что и «tic» и «toc». Обычно 'tic' и' toc' используются для быстрых и грязных проверок, в то время как 'timeit' может обеспечить лучшие результаты. Однако, если у вас много строк и вы хотите быстро увидеть, какие из них занимают много времени, вы можете использовать профилировщик. –

3

Профилировщик - одна из возможностей, но это значительно замедлит ваш код. В качестве альтернативы вы можете сохранить значение toc в вашем цикле или после каждого вызова функции.

t(i) = toc 

, а затем сравнить эти значения, вычислить среднее значение или что угодно, как если бы вы имели дело с другими векторами.

+0

Почему профайлер замедляет мой код. Пожалуйста, объясните. – roni

+1

Он анализирует гораздо больше, чем простое время, и уже оценивает определенные промежутки времени. Но, возможно, вам не нужны дальнейшие вычисления, потому что профилировщик предлагает всю необходимую вам информацию. испытайте его;) – thewaywewalk

+0

Я попробую и опубликую результаты в ближайшее время! – roni

Смежные вопросы