From f1222a5dd58fea993cc7bed777e563d5d5ad27ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Edelbo?= Date: Fri, 16 Aug 2019 12:27:04 +0200 Subject: [PATCH] Optimize Array::find_optimized in case of Equal on nullable array --- src/realm/array.hpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/realm/array.hpp b/src/realm/array.hpp index 604da1fcfa2..cd3b0dde160 100644 --- a/src/realm/array.hpp +++ b/src/realm/array.hpp @@ -2219,19 +2219,32 @@ bool Array::find_optimized(int64_t value, size_t start, size_t end, size_t basei end = nullable_array ? size() - 1 : size(); if (nullable_array) { - // We were called by find() of a nullable array. So skip first entry, take nulls in count, etc, etc. Fixme: - // Huge speed optimizations are possible here! This is a very simple generic method. - auto null_value = get(0); - for (; start2 < end; start2++) { - int64_t v = get(start2 + 1); - bool value_is_null = (v == null_value); - if (c(v, value, value_is_null, find_null)) { - util::Optional v2(value_is_null ? util::none : util::make_optional(v)); - if (!find_action(start2 + baseindex, v2, state, callback)) - return false; // tell caller to stop aggregating/search + if (std::is_same::value) { + // In case of Equal it is safe to use the optimized logic. We just have to fetch the null value + // if this is what we are looking for. And we have to adjust the indexes to compensate for the + // null value at position 0. + if (find_null) { + value = get(0); } + start2++; + end++; + baseindex--; + } + else { + // We were called by find() of a nullable array. So skip first entry, take nulls in count, etc, etc. Fixme: + // Huge speed optimizations are possible here! This is a very simple generic method. + auto null_value = get(0); + for (; start2 < end; start2++) { + int64_t v = get(start2 + 1); + bool value_is_null = (v == null_value); + if (c(v, value, value_is_null, find_null)) { + util::Optional v2(value_is_null ? util::none : util::make_optional(v)); + if (!find_action(start2 + baseindex, v2, state, callback)) + return false; // tell caller to stop aggregating/search + } + } + return true; // tell caller to continue aggregating/search (on next array leafs) } - return true; // tell caller to continue aggregating/search (on next array leafs) }