cocoa text handling is a huge CPU drain

Among other challenges in bringing an older app up to cocoa and the latest xojo version has been a very simple log window. Under carbon this was no problem. The window stores around 30k of styled text. With each added line I check the length of the entire field and then delete some off the top as I add another line onto the bottom. I did the adding and deleting by moving the insertion point and setting the seltext, either to the new line, or to an empty string in order to remove old entries off the top. I wasn’t resetting the entire 30k each time.

The app used a huge amount more CPU after moving to carbon and I narrowed it down to rendering that log window. I understand that the textField is now a much more capable control than it used to be and I turned off as much of that as I could like spell checking but it made no difference. Then I dived into the MBS plugins and turned off ALL the options that there were flags for there, all the special kerning and ligatures and grammar checking and everything else. No difference.

If I logged too many lines in a second the entire app would spin the beach ball and refuse all other input.

I replaced the entire thing with a listbox that just adds colored lines of text or pops them off the top and the difference is amazing. The listbox stores 2000 lines which is far more than the old field ever could hold. using a textField storing 30k of text my app averaged 70% of the CPU with elongated spikes over 90% (this is a 2 year old mini) with the listbox managing it the CPU usage is 10% with spikes as high as 15%.

I can’t believe that no matter what it’s trying to do with text encoding and rendering a bazillion characters that it should be that difficult. What is going on with the TextField?

try making sure background tasks are disabled when you begin you update process
and also set the TextArea.VISIBLE to FALSE, reseting it to true when the update is complete

This will cause the TextArea to not refresh itself everytime you change or move something, and since it is all within the same process flow (the visible=false … update … visible=true), the control should not even flicker

Perhaps this older Speeding TextArea Modifications under Cocoa blog post might be helpful:

http://www.realsoftwareblog.com/2012/11/speeding-up-textarea-modifications.html

I will experiment with those both, thank you folks.

James, same problem here. When you use a Listbox, how do you handle line wrapping with the “all the same row height”-Listbox?
I thought of getting the string’s graphical length (using draw string) and adapting that to the Listbox’ width, creating a new row, if it wraps.
But then, if the user resizes the Listbox, all would have to be new computed and re-created… And a smooth resize would’nt be possible also…
Have you found another way?

The listbox works great for CPU usage, but wrapping is an issue. For my app I’m not even worrying about it right now, it’s a log output and if someone wants to they can open the file in a real text editor.

I have not experimented with the other suggestions above of either hiding the text control or properly telling it that a bunch of updates are coming and to not worry about reprocessing the contents until it’s ready to be displayed again. Have you tried those?

You will most probably find that the BeginEditing and EndEditing calls will solve your problem. It’s not that a TextView would be that slow, it is because there’s legions of methods working on it every time you change something. With Begin and EndEditing you disable those automatisms which will get you literally 100X the speed compared to when they are enabled.