MacOS Tahoe painfully slow a wxChoice containing 6k entries.

46 views
Skip to first unread message

Tony Kennedy

unread,
Dec 10, 2025, 4:31:15 AM (7 days ago) Dec 10
to wx-users
Hi all,

Using MacOS Tahoe and wx 3.3.0.0.

A user has reported that there is a crazy slowdown when using MacOS Tahoe.

The offending line in my code is 

m_pChoice->Clear();

The wxChoice control has 6500 entries and takes approximately a minute to clear all entries.

Has anyone else experienced something similar?

All is fine on both Windows and other versions of MacOS. And previous versions of my app that used earlier wx (3.2.6) is also fine.

Any advice would be very welcome.

Thanks in advance,

Tony.

Tony Kennedy

unread,
Dec 10, 2025, 5:12:33 AM (7 days ago) Dec 10
to wx-users
An update as this potentially impacts all MacOS controls that have a NSMenu internally.

I had a feeling it was "Spotlight" that was the problem based on https://discussions.apple.com/thread/256145409?sortBy=rank.

Using chatgpt (I'm not familiar with Apple and Spotlight which seems to be the cause of the problem), it gave me a workaround.

From chatgpt,
On macOS, wxChoice is implemented using a native NSPopUpButton, which internally creates an NSMenu with 6000 NSMenuItems. macOS Spotlight/Accessibility automatically scans every NSMenuItem for metadata every time the menu changes — especially when
  • clearing all items

  • recreating items

  • calling Clear()

  • calling Append() thousands of times

This is why your app hangs for 60+ seconds.


Two solutions.

1. Don't use "Clear", instead create a wxArrayString object, add all the strings and then call pChoice->Set(items);


2. Replace wxChoice with wxOwnerDrawnComboBox.

#if defined(__WXMAC__)
    #define WX_CHOICE wxOwnerDrawnComboBox
    #define WX_CHOICE_FLAGS(parent, id, value, pos, size, choices, style) \
        wxOwnerDrawnComboBox(parent, id, value, pos, size, choices, style)
#else
    #define WX_CHOICE wxChoice
    #define WX_CHOICE_FLAGS(parent, id, value, pos, size, choices, style) \
        wxChoice(parent, id, value, pos, size, choices, style)
#endif

and then replace

wxChoice* myChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, items);

with

WX_CHOICE* myChoice = WX_CHOICE_FLAGS(this, wxID_ANY, wxEmptyString,
                                      wxDefaultPosition, wxDefaultSize,
                                      items, 0);












Tony Kennedy

unread,
Dec 10, 2025, 5:41:54 AM (7 days ago) Dec 10
to wx-users
Sadly it's not going to be as simple as solution 2 above as any "Bind(wxEVT_CHOICE" on the control will need reworking.

Tony Kennedy

unread,
Dec 10, 2025, 6:09:41 AM (7 days ago) Dec 10
to wx-users
Another update as I should have tested these out before posting.

"Solution 1" does not work, it's still slow.

Vadim Zeitlin

unread,
Dec 10, 2025, 9:09:59 PM (6 days ago) Dec 10
to wx-u...@googlegroups.com
On Wed, 10 Dec 2025 01:31:15 -0800 (PST) Tony Kennedy wrote:

TK> The wxChoice control has 6500 entries and takes approximately a minute to
TK> clear all entries.

Recommended maximum number of elements for simple controls like wxChoice,
wxComboBox, wxListBox etc is a hundred entries, a couple of hundreds at
most. How can a user possibly select anything in a control with several
thousands of them?

TK> Any advice would be very welcome.

My first advice is to not use wxChoice for this. Maybe you could create
wxWindowUpdateLocker for it before clearing it (and maybe this could be
done by Clear() itself) and perhaps something else could be optimized in
its implementation (it might be deleting items one by one currently instead
of removing them all at once) but it was never supposed to be used with
such numbers of items anyhow.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
https://www.tt-solutions.com/

Tony Kennedy

unread,
Dec 11, 2025, 3:08:11 AM (6 days ago) Dec 11
to wx-users
I agree, there are too many entries. The correct way in the app is to array the entries in the choice control (so one entry can have thousands of sub-entries). But a user has copied/pasted instead resulting in the large number of entries. I'm sure we all ask ourselves the same question "why have they done this?" all the time.

I'm back up and running now with a wrapper class around wxOwnerDrawnComboBox. I'll share it once I've had some feedback regarding testing.

I also tried wxWindowUpdateLocker (I use that all the time), it didn't make a difference.

All the best,

Tony.



Reply all
Reply to author
Forward
0 new messages