Steps to reproduce:
I've been getting frequent temporary beachballs, sometimes over 10 seconds long, while using Orion.
Using Instruments and Frida I've narrowed down the path where this happens:
- Some function on the main thread posts the notification
- This calls
BookmarksBarItem.iconUpdated (synchronously on the same thread).
- One of the functions called from this eventually executes a SQLite query of the form:
SELECT ICON_HASH FROM (
REPLACE(REPLACE(REPLACE(favicon.PAGE_URL, 'www.', ''), 'http://', ''), 'https://', '') as _PAGE_URL
LEFT JOIN icon_info ON icon_info.HASH = favicon.ICON_HASH
(_PAGE_URL = 'xxx' OR _PAGE_URL = 'xxx/') AND icon_info.ICON_TYPE = 0 AND icon_info.WIDTH >= 0
xxx is a webpage URL, either from my bookmarks or one that I'm currently visiting.)
- This query does a linear scan over all rows of the
favicon table, which for me has 27,768 rows.
- Most of the time the query takes around 33ms, but sometimes it takes orders of magnitude longer, up to multiple seconds. I am honestly baffled at this discrepancy, given that it's scanning over the same data. You would think that this would indicate the thread waiting for a lock or not being scheduled or paging from swap, but Instruments suggests that the thread is actively running and spending most of its time taken in
replaceFunc, which is a function in libsqlite3.dylib that implements the
REPLACE SQL function. Yet I verified that it calls the
replaceFunc the same number of times with the same arguments. (And regarding swap specifically, my system has enough memory that it currently shows 0 bytes of swap used, even though I reproduced beachballs recently.) Could it have something to do with P-cores versus E-cores?
- Cache the
REPLACE output in a different SQL column and add an index for that column, so that you can query for a specific URL without doing a linear scan over all rows in the table.
- Have the notification handler dispatch the work to a background queue, so that the SQL query doesn't block the main thread even if it is slow.
Orion, OS version; hardware type:
Orion Version 0.99.123.1-beta (WebKit 6184.108.40.206)
MacBook Pro (macOS Ventura 13.1 build 22C65)