Благодаря превосходному post Яир Альтману на undocumentedmatlab.com, я попытался внедрить программу ведения графического интерфейса с использованием богатого editbox и базовых компонентов Java. Вот упрощенная версия кода:Улучшение производительности на графике GUI
Сначала код, чтобы создать панель
function jEditbox = logPanel()
hFig = figure('color', 'w');
hPanel = uipanel(hFig);
% Prepare the log editbox
hLogPanel = uicontrol('style', 'edit', 'max', 5, 'Parent', hPanel, ...
'Units', 'normalized', 'Position', [0, 0.2, 1, 0.8], 'Background', 'w');
% Get the underlying Java editbox, which is contained within a scroll-panel
jScrollPanel = findjobj(hLogPanel);
try
jScrollPanel.setVerticalScrollBarPolicy(jScrollPanel.java.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPanel = jScrollPanel.getViewport();
catch %#ok<CTCH>
% may possibly already be the viewport, depending on release/platform etc.
end
jEditbox = handle(jScrollPanel.getView, 'CallbackProperties');
% Prevent user editing in the log-panel
jEditbox.setEditable(false);
% Set-up a Matlab callback function to handle hyperlink clicks
set(jEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);
% Ensure we have an HTML-ready editbox
HTMLclassname = 'javax.swing.text.html.HTMLEditorKit';
if ~isa(jEditbox.getEditorKit, HTMLclassname)
jEditbox.setContentType('text/html');
end
end
Тогда код протоколирования:
function logMessage(jEditbox, text)
% newText = [iconTxt, msgTxt ' '];
text = [text '<br/>'];
% Place the HTML message segment at the bottom of the editbox
currentHTML = char(jEditbox.getText);
newHTML = strrep(currentHTML, '</body>', text);
jEditbox.setText(newHTML);
endPosition = jEditbox.getDocument.getLength;
jEditbox.setCaretPosition(endPosition);
end
я две проблемы:
Существуют серьезные проблемы с производительностью в приложениях, для которых требуется большое количество зарегистрированных сообщений (т.е.> 500). Используя профайлер и следующий код (обратите внимание, что я изменил
why
, чтобы вернуть строку, а не печатать в командной строке), я видел, что узким местом являетсяsetText()
. Может ли кто-нибудь объяснить, что такое шипы на графике?h = logPanel(); n = 1e3; time = nan(n, 1); profile on for i = 1:n tic logMessage(h, why) time(i) = toc; end profile viewer avgTime = mean(time); figure('color', 'w') bar(time) hold on plot([0, n], avgTime*ones(1, 2), '-k', 'LineWidth', 2) hold off title(sprintf('Average Time = %f [s]', avgTime));
Если добавить
pause(0.1)
послеtoc
, то граф выглядитЧто здесь происходит?
В результате получается очень «блестящая» панель журнала. Каждый раз, когда я пишу сообщение, содержимое мерцает при прокрутке вверх, а затем назад. Еще раз этот дефект вызван
setText()
, который заставляет каретку начинаться с документа.
Я ищу решения любой из этих проблем, желательно и то, и другое.
Среднее время между 4 и 16 миллисекундами на моих OSX 10.8 и R2012b, без 'pause (0.1) ' – marsei
Кажется, что R2013b менее эффективен в этом отделе, чем R2012b. Я пробовал это на 2012b и получил аналогичные результаты, как вы. Попробуйте запустить тест с большим значением 'n' (например, 5000). Я все еще сильно замедляюсь. – hoogamaphone
Я не знаю, что случилось с 'getText()', чтобы быть узким местом, но я бы поставил себе представление о том, что после «toc» или перед 'tic' вы будете сбрасывать' tic', вы увидите подобное изменение. Если моя интуиция правильная, то несоответствие происходит из-за очереди событий (возможно, графических объектов), которая сбрасывается по одному из методов 'jEditbox' (вероятно,' getText'). – chappjc