Bug #7088
Lazily initialize activeBundle inside RandomAccessQuery
0%
History
#1 Updated by Alexandru Lungu over 3 years ago
There is relevant activity when building an activeBundle in general, mostly related to FQL composition (createBundle, buildSortClause, preprocessWhere).
RandomAccessQuery.execute uses the ffCache (if exists) when the bundle key is FIRST, LAST or UNIQUE (+ other safety conditions). In the best case, we have a cache hit and we can retrieve the record from the session cache or hydrate. Therefore, I don't see any usage of activeBundle in this case, so we can avoid the creation of the FQLs if we can resolve the query through ffCache.
It may be safe to retrieve activeBundle through a getter which lazily sets it depending on the activeBundleKey. This way, it will be set only when needed. Furthermore, activating (e.g. using activateLast), activeBundle can be set on null to suggest the fact that it should be reassigned.
This way, having a ffCache for a RandomAccessQuery converted from a stand-alone FIND FIRST tt WHERE [...] can bypass the creation of activeBundle altogether.
#2 Updated by Eric Faulhaber over 3 years ago
This makes sense. Although the cost currently is mitigated to some degree by caching in FQLHelper, there is still work to create a key, check the cache, do some substitution parameter processing, etc. So, I agree with your premise. In terms of prioritizing this work, are you finding this is a hotspot?
#3 Updated by Alexandru Lungu over 3 years ago
I've done a slim test with ~40,000 find queries. ~13.000 of them used ffCache. The total time spent on activation was 8ms (out of which 2ms were spent for the finds resolved by ffCache). This makes this the optimization look very weak.
Eric Faulhaber wrote:
This makes sense. Although the cost currently is mitigated to some degree by caching in
FQLHelper, there is still work to create a key, check the cache, do some substitution parameter processing, etc. So, I agree with your premise. In terms of prioritizing this work, are you finding this is a hotspot?
I was not hoping just to avoid the FQLHelper cache look-up and bundle building, but to avoid the whole helper and FQLPreprocessor work. Simply doing a lazy activeBundle initialization is not enough. Most of the important API of RAQ (first, unique, last, next, previous) require the helper before using the ffCache.
ffCache is to be used". This is achievable as most (or even all) of the getHelper calls are used for very specific isolated use-cases:
- all
RAQAPI checkgetHelper().getFQLPreprocessor().isFindByRowid()to eventually transform into unique (maybe it can be refactored? or delayed?) initializeusesgetHelper().getFQLPreprocessor().isFindByRowid()to do logging (can be omitted)uniqueusesgetHelper()to checkisFindTemplateorfqlPreprocessor.getFindByRowid(values) < 0(very rare cases)ffCacheuseswherestring inside the cache key. However, it also retrieves the query properties (from the helper) for the cache key: is this part of lazy-hydration? can we makeffCachepurely independent upon the helper?
Having all that ~13.000 fast-find queries avoid any FQL work should result in more that 2ms performance increase.