What is TextContro​l>TextCont​rol.proces​s listed when profiling appdesigner code (Matlab 2021b)?

I am writing an application using appdesigner in Matlab 2021b. I have been using the profiler to understand how to improve the response times of the application display, and the most time consuming function name is always listed as 'TextControl>TextControl.process' as follows:
To improve the response time of my application, I have been reducing the number of calls to plot() and text(), and this has been quite helpful. But I am finding this 'TextControl' function calls entry hard to understand, so it is not so easy to progress further. Any suggestions would be appreciated.

댓글 수: 10

What components does the app consist of and how are you executing the code to profile it?
In terms of the graphics, the app consists of two axes with a variety of menu items and slider bars.
(1) for the first axes, we have a background image shown using a imagesc command with ~400 boxes (drawn with plot) each with a text label (placed with the text() command).
(2) for the second axes, we draw ~2000 quiver objects, each of which also has a text box. Our main speedup has been to use a single quiver() and text() command to draw the objects in this panel.
To profile this, we just start the profiler without any entry
And then just click on one of the user controls (in this case a slider bar), let the application update the two axes, and then stop the profiling. What I am curious about is that the number of calls to this TextControl.process function is about equal to the number of quiver objects in the second panel...
"..., we draw ~2000 quiver objects, each of which also has a text box. .... What I am curious about is that the number of calls to this TextControl.process function is about equal to the number of quiver objects in the second panel..."
Well, yes, I would think that not surprising that it has to update every text box in the app and that that UIControl overhead is the major factor in such a scenario.
To test that, can you copy the app into a second version and just cut down the number of those text boxes by, say, half, and then time it? If it is essentially linear with number, I think you'll have the answer to the question.
Then the Q? becomes one of why do you need 2,000 text boxes in the first place? Nobody is going to be reading/editing that many and how could you get them all on the screen, anyways?
What's the end result desired for the user? A redesign of the interface may be in order here...
Thanks for your comments and suggestions. I agree with your observations.
Yes, I have done this test to vary the number of text boxes and see the linearity very clearly.
I guess my question is whether one can plot these 'text' boxes without the UIControl overhead. I am not interested in editing or clicking on these text boxes. I just want to place some labels. Perhaps text() is not the appropriate command to use?
". I just want to place some labels...."
Then just use the uilabel object instead for static text labels. I've not checked about whether it has essentially the same overhead as a text() object or not; it can be set statically in AppDesigner as opposed to being called programmatically; I also do not know otomh if that makes any difference in the inherent overhead; I've never had such a volume of components it mattered...but I would guess it would be the same as to whether were created programmatically or by placing them in the app in design view (essentially an impossible task for 2,000 of them I'd think).
It's the only thing I can think of with individual objects that might help a little; the other alternatives would have to do with using a table or something that is a single object able to hold more than one piece of data -- but it would have to be a container for all or a large fraction of these individual components and would be in one place, not scattered all over the universe....hence the earlier comment about redesigning the UI; the present idea just sounds to me as though it is probably unworkable to have any response time. Although you can see if if the labels are enough better than text to help measurably...even if they're 2X the speed, it would still seem to be way too much,though. You'd need 10X to even be close to workable I'd think and more like 100X and I don't think thassagonna happen...
Thanks very much for your comments. Much appreciated.
I guess it would be nice to be able to turn off some of the text object overhead.
Are you writing in one or a few calls to text() with an array of coordinates or in a loop one at a time? While the vectorized call still creates an array of handles, it should be faster than calling each location individually.
Still, replacing the text() control with the label if they are indeed static should help and it may also be that after initial startup the static controls won't be in the way because they will not generate any callbacks--but initialization/startup may still be quite long.
I did some very rudimentary tests here, but not in app designer with regular and UI figures...
>> axes();
>> N=1000;
>> hT=gobjects(N,1);
>> tic;for i=1:N,hT(i)=text(0.5,0.5,'Hello'); end, toc
Elapsed time is 0.648489 seconds.
>> x=0.5*ones(size(hT)); y=x;
>> txt=repmat({'Hello'},size(hT));
>> delete(hT)
>> tic;hT=text(x,y,txt);toc
Elapsed time is 0.555180 seconds.
>> delete(hT)
>> tic;hT=text(x,y,txt);toc
Elapsed time is 0.566641 seconds.
The normal text into regular axes is a little faster when vectorized, but not a whole lot--15% or so above. Interestingly, not preallocating hT for object handles was consistently a little faster than indexing into the graphics objects array such that the difference between the loop and vectorized calls was only 10% or even less. That's somewhat counterintuitive; one would still think it would be faster to index into the existing object.
Then I tried same with a uifigure/uiaxes instead to see the difference it makes...
>> hUF=uifigure;
>> hUAx=uiaxes(hUF);
>> tic;for i=1:N,hT(i)=text(hUAx,0.5,0.5,'Hello'); end, toc
Elapsed time is 0.630968 seconds.
>> delete(hT)
>> tic;hT=text(hUAx,x,y,txt);toc
Elapsed time is 0.587351 seconds.
>> delete(hT)
>> tic;for i=1:1,hT(i)=uilabel(hUAx,'Text','Hello','Position',[10 10 50 20]); end, toc
Error using uilabel (line 36)
UIAxes cannot be a parent.
>> delete(hUAx)
>> tic;for i=1:N,hT(i)=uilabel(hUF,'Text','Hello','Position',[10 10 50 20]); end, toc
Elapsed time is 1.809283 seconds.
>>
There is little difference in timing between writing a text() object to the uiaxes as compared to the normal axes.
However, one can't put a label inside an axes and it was a factor of 3X slower than was text() plus it cannot be vectorized. It would appear my supposition about labels being the better choice was wrong.
However, simply writing to the text() objects didn't seem to make much difference about being in the uifigure environment that would be the app configuration. That would appear to make the much longer timings you're seeing something that must be specific to either the design layout used or simply a byproduct of building an app with app designer somehow; peformance in simply writing to the text boxes themselves did not appear to suffer much.
Ergo, I suspect it would take delving into the actual app UI design itself to be able to ascertain anything additional about just what is the overhead you're seeing.
It might be worth paring it down to a much smaller number of components and seeing if there is some "knee" at which the penalty suddently drops markedly or if the behavior remains as is in a percentage basis all the way down to a small number like 10 or 5. If it does, is there any possibility that along with all those text boxes you're also loading large amounts of data and maybe you ran into a caching or disk thrashing problem? Don't know why that would show up as related to the text box rendition, though...
Thank you very much for your observations. Most instructive and informative. I already have selectively been cutting down on the number of text labels I have been using which has been helpful.
Also, when I vectorize the addition of text and box placement when redrawing the UI, I am seeing about a factor of 10 speed up (~roughly 45-50 seconds down to about 5 seconds), but I still see the same overhead. That is, I do better with shortening the blue bars in my flame diagram above and below here, but still see the same overhead.
I was studying the flame diagram more closely. It is quite logical now that I am spending more time with it. It more or less divides into 3 parts. The first part circled in red is where all my text boxes seem to be responding in some fashion to my UI change (move a slider bar or click a menu item), then I am redrawing my two axes (indicated in green), and then there is a registration section of sorts that I am circling in purple. I've blown up that third section in the next figure.
Here we clearly see that there is some registration of text control. Hard for me to understand what is happening here.
As you already highlighted, these behaviors seem to be coming from how I am designing my UI in appdesigner.
When I am reading the documentation about Text Properties, specifically the section on Interactivity, I am seeing properties for 'Editing' which is by default 'off', 'Visible' which is by default 'on' (that's good), 'ConextMenu' which is 'empty' by default, 'Selected' which is 'off' by default, 'selectionHighlight' which is 'on', and 'Interactions' which is empty by default.
I typically try to avoid getting into the weeds of these kinds of settings but I will look through this some more.
"..., 'Visible' which is by default 'on' (that's good),"
One thing that is a trick in speeding up (apparent) response time with graphics is actually to draw into a hidden axes ('Visible','off') and then, when finished, make it the visible and hide/delete the previous. With the graphics visible, the background processes to cause screen updates will trigger whenever anything gets modified whereas if it is not visible, then the engine knows there is no need to actually refresh the screen. I've never tried this inside AppDesigner with its user controls, but if you could manage to arrange the UI such that all you need to update for the interactive controls is in an active panel and all the display information being updated in responsee is in another that can do while invisible and then only make visible when done, you might be able to make some more progress.
If it is feasible to build a very small replica of the idea with sufficient data to be able to illustrate the functionality, upload that .mlapp file and perhaps some others will be inspired to try to look into it more fully. My GUI building has been extremely limited to very small UI interfaces (I was always able to offload that part to others who specialized in those areas while I dealt with the computational side) so my in depth expertise is quite limited...plus, I have some other immediate time-dependent tasks so I really don't have time to delve much more deeply other than what can do in a few minutes' break now and then...

댓글을 달려면 로그인하십시오.

답변 (0개)

카테고리

도움말 센터File Exchange에서 Text Data Preparation에 대해 자세히 알아보기

제품

릴리스

R2021b

질문:

2024년 9월 30일

댓글:

dpb
2024년 10월 1일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by