java - Improve Performance On GUI log -
thanks yair altman's excellent post on undocumentedmatlab.com, i've tried implement gui logging program using rich editbox , underlying java components. here simplified version of code:
first code create panel
function jeditbox = logpanel() hfig = figure('color', 'w'); hpanel = uipanel(hfig); % prepare log editbox hlogpanel = uicontrol('style', 'edit', 'max', 5, 'parent', hpanel, ... 'units', 'normalized', 'position', [0, 0.2, 1, 0.8], 'background', 'w'); % underlying java editbox, contained within scroll-panel jscrollpanel = findjobj(hlogpanel); try jscrollpanel.setverticalscrollbarpolicy(jscrollpanel.java.vertical_scrollbar_as_needed); jscrollpanel = jscrollpanel.getviewport(); catch %#ok<ctch> % may possibly viewport, depending on release/platform etc. end jeditbox = handle(jscrollpanel.getview, 'callbackproperties'); % prevent user editing in log-panel jeditbox.seteditable(false); % set-up matlab callback function handle hyperlink clicks set(jeditbox,'hyperlinkupdatecallback',@linkcallbackfcn); % ensure have html-ready editbox htmlclassname = 'javax.swing.text.html.htmleditorkit'; if ~isa(jeditbox.geteditorkit, htmlclassname) jeditbox.setcontenttype('text/html'); end end then logging code:
function logmessage(jeditbox, text) % newtext = [icontxt, msgtxt ' ']; text = [text '<br/>']; % place html message segment @ bottom of editbox currenthtml = char(jeditbox.gettext); newhtml = strrep(currenthtml, '</body>', text); jeditbox.settext(newhtml); endposition = jeditbox.getdocument.getlength; jeditbox.setcaretposition(endposition); end i have 2 problems:
there major performance issues in applications require large number of logged messages (i.e. > 500). using profiler , following code (note i've modified
whyreturn string rather printing command line), i've seen bottlenecksettext(). can explain spikes in graph are?h = logpanel(); n = 1e3; time = nan(n, 1); profile on = 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));
if add
pause(0.1)aftertoc, graph looks like
what's going on here?
this results in "flashy" log panel. each time write message, contents flicker scrolls top , bottom. once again, defect due
settext(), forces caret beginning of document.
i'm looking solutions either of these problems, preferrably both.
of course, using gettext(), string manipulation , settext() bottleneck. force editor component convert it’s entire contents html representation , reparse entire html representation after change. editor not able detect added bit of text. more contents component has, higher performance loss.
if have swing text component , want append text @ end can use:
(the easy one) plain text:
textcomp.setcaretposition(textcomp.getdocument().getlength()); textcomp.replaceselection("\nmore text");(not harder) text in content type, e.g. html:
document doc = textcomp.getdocument(); textcomp.geteditorkit().read( new stringreader("more <i>styled</i> text"), doc, doc.getlength());
in second case, if want move caret end have add setcaretposition invocation in first case.
Comments
Post a Comment