почему Matlab медленно работает в цикле for с большим количеством итераций, но быстро с небольшим количеством итераций?

Я запускаю функцию для извлечения некоторой информации из более чем 100 000 файлов рентгеновских снимков пациентов. файлы хранятся в контейнере шифрования veracrypt в целях безопасности.

когда я запускаю функцию для небольшой выборки файлов, она работает очень быстро, однако, когда я запускаю функцию для всего набора данных, она очень медленная по сравнению с несколькими файлами в секунду до 1 файла в секунду (приблизительно).

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

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

спасибо за любую помощь.

function [ DB, corrupted_files ] = extract_from_dcm( folder_name )
%EXTRACT_FROM_DCM Summary of this function goes here
%   Detailed explanation goes here

if nargin == 0
    folder_name = 'I:\Find and Treat\MXU Old Backup\2005';
end

Database_Check = strcat(folder_name, '\DataBase.mat');

if exist(Database_Check, 'file')

    load(Database_Check);
    entry_start = length(DB) + 1;

else

    entry_start = 1;
    [ found_dicoms ] = recursive_search( folder_name );

end

mat_file_location = strcat(folder_name, '\DataBase.mat');
excel_DB_file = strcat(folder_name, '\DataBase.xlsx');
excel_Corrupted_file = strcat(folder_name, '\Corrupted_Files.xlsx');

% the recursive search creates a struct with the path for each
% dcm file found. the list is then recursivly used to locate
% the image and extract the relevant information from it.


fprintf('---------------------------------------------\n');
fprintf('Start Patient Data Extraction\n');
tic
h = waitbar(0,'','Name','Patient Data Extraction');
entry_end = length(found_dicoms);

if entry_end == 0
    %     set(handles.info_box, 'String', 'No Dicom Files Found in this Folder or its Subfolders');
else
    %     set(handles.info_box, 'String', 'Congratulations Dicom Files have been found Look Through the Data Base using the Buttons Below....Press Save Button to save the Database. (Database Save format is EXCEL SpreadSheet and MAT file');

    for  kk = entry_start : entry_end
        progress = kk/entry_end;
        progress_percent = round(progress * 100);
        waitbar(progress,h, sprintf('%d%%   %d/%d of images processed', progress_percent, kk, entry_end));

        img_full_path = found_dicoms(kk).name;

        %         search_path = folder_name;
        %         img_full_path = strrep(img_full_path, search_path, '');

        try              %# Attempt to perform some computation
            dicom_info = dicominfo(img_full_path); %# The operation you are trying to perform goes here

            try              %# Attempt to perform some computation
                dicom_read = dicomread(dicom_info); %# The operation you are trying to perform goes here

                old = dicominfo(img_full_path);

                DB(kk).StudyDate = old.StudyDate;
                DB(kk).StudyTime = old.StudyTime;


                if isfield(old.PatientName, 'FamilyName')
                    DB(kk).Forename = old.PatientName.FamilyName;
                else
                    DB(kk).Forename = 'NA';
                end

                if isfield(old.PatientName, 'GivenName')
                    DB(kk).LastName = old.PatientName.GivenName;
                else
                    DB(kk).LastName = 'NA';
                end

                if isfield(old, 'PatientSex')
                    DB(kk).PatientSex = old.PatientSex;
                else
                    DB(kk).PatientSex = 'NA';
                end

                if isempty(old.PatientBirthDate)
                    DB(kk).PatientBirthDate = '00000000';
                else
                    DB(kk).PatientBirthDate = old.PatientBirthDate;
                end

                if strcmp(old.Manufacturer, 'Philips Medical Systems')
                    DB(kk).Van = '1';
                else
                    DB(kk).Van = '0';% section to represent organising by different vans
                end

                DB(kk).img_Path = img_full_path;

                save(mat_file_location,'DB','found_dicoms');

            catch exception  %# Catch the exception
                fprintf('read - file %d corrupt.\n',kk);
                continue       %# Pass control to the next loop iteration
            end



        catch exception  %# Catch the exception
            fprintf('info - file %d corrupt.\n',kk);
            continue       %# Pass control to the next loop iteration
        end


    end

end


[ corrupted_files, DB ] = corruption_check( DB, found_dicoms, folder_name );


toc
fprintf('End Patient Data Extraction\n');
fprintf('---------------------------------------------\n');

fprintf('---------------------------------------------\n');
fprintf('Start Saving Extracted Data \n');
tic


save(mat_file_location,'DB','corrupted_files','found_dicoms');

if isempty(DB)
    msg = sprintf('No Dicom Files Found');
    msgbox(strcat(msg));
else
    DB_table = struct2table(DB);
    writetable(DB_table, excel_DB_file);
end

close(h);

toc
fprintf('End Saving Extracted Data \n');
fprintf('---------------------------------------------\n');

end

person bilaly    schedule 20.04.2015    source источник
comment
Просто бросаю это туда без каких-либо подтверждающих доказательств: вам действительно следует предварительно выделить этот массив DB, и это не похоже на то, что вы делаете ... Вы знаете, сколько элементов будет, особенно entry_end - entry_start + 1. Matlab должен предупредить вас об этом, когда вы делаете DB(kk), поскольку это может привести к перераспределению, поскольку вы продолжаете изменять его размер (что довольно медленно). Чтобы убедиться в этом, запустите профилировщик.   -  person Rollen    schedule 20.04.2015
comment
Обновление этой панели ожидания, вероятно, будет стоить вам много времени выполнения. Обновления графики в цикле стоят очень дорого. Попробуйте прокомментировать это, чтобы увидеть, поможет ли это. А еще лучше использовать профайлер.   -  person siliconwafer    schedule 20.04.2015
comment
круто, спасибо, да, я планирую сделать предварительное распределение и посмотрю на панель ожидания. проблема в том, что в коде чем больше цикл, тем медленнее он становится, я не могу понять, почему это так.   -  person bilaly    schedule 20.04.2015
comment
Что ж, посмотрите, удалят ли эти изменения его (вероятно, что перераспределение может привести к замедлению его работы по мере его увеличения, возможно, это верно и для панели ожидания), но если нет, вы должны собрать tic/tocks для каждой итерации и показать снижение производительности, а также использовать профилировщик, чтобы сузить проблему. .   -  person Rollen    schedule 20.04.2015
comment
Я сделал предварительное распределение и использовал профилировщик, но заметной разницы не было. При обработке изображений в 10 тысяч это все еще намного медленнее для каждого изображения, чем при работе с изображениями в сотнях. я не удалял панель ожидания, так как она мне действительно нужна, чтобы отслеживать, какое изображение обрабатывается в данный момент.   -  person bilaly    schedule 20.04.2015
comment
@bilaly ммм ... вы должны опубликовать результаты своего профилировщика (и тик/токс, чтобы показать, что производительность действительно замедляется по мере повторения, или это случайный всплеск, а не усреднение)? Вы проверили, какие строки кода самые медленные? Кроме того, почему вы сохраняете вектор DB на каждой итерации цикла? почему бы и нет... после завершения?   -  person Rollen    schedule 20.04.2015
comment
я буду повторно запускать все тесты и публиковать результаты (это займет некоторое время).. я сохраняю БД (которая представляет собой структуру, содержащую извлеченные данные пациента) каждый раз, чтобы иметь возможность отменить операцию и выбрать, где я остановился позже, не повторяя те же изображения снова, так как их так много для обработки, и я не могу позволить компьютеру работать непрерывно, пока он не завершит работу сам по себе.   -  person bilaly    schedule 20.04.2015


Ответы (1)


Хорошо, спасибо за помощь..

Моя проблема заключалась в сохранении в конце каждой итерации, но самой большой проблемой была строка, в которой я запускаю функцию dicomread. я изменил сохранение для каждых 20 обработанных изображений.

Я также удалил предварительное выделение, предложенное в комментариях, чтобы увидеть, какая разница, без dicromread и сохранения набухания. это было значительно медленнее, чем с предварительным распределением.

... мне просто нужно найти решение для dicomread (которое я использовал как способ проверить, поврежден ли файл или нет).

person bilaly    schedule 20.04.2015
comment
Я бы хотел, но мне нужно подождать 2 дня, прежде чем я смогу его принять. - person bilaly; 21.04.2015