From 4421e7c33eb255aaa4fdbd442a4e1f17434bfb55 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Thu, 23 Jan 2025 20:20:22 +0000 Subject: Optimize field lookup. Try indexing directly in the array, or close to the given index. Test: test.py Change-Id: I3260edf7a0c54de241f71dbbb31d2efb1c4103c8 --- runtime/mirror/class.cc | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'runtime/mirror/class.cc') diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index fe923cbaa6..0bf1b1cc0a 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -1173,10 +1173,31 @@ ArtField* Class::FindDeclaredStaticField(std::string_view name, std::string_view } ArtField* Class::FindDeclaredField(ObjPtr dex_cache, uint32_t dex_field_idx) { - if (dex_cache == GetDexCache()) { - for (ArtField& field : GetFields()) { - if (field.GetDexFieldIndex() == dex_field_idx) { - return &field; + size_t num_fields = NumFields(); + if (dex_cache == GetDexCache() && num_fields > 0) { + // The field array is an ordered list of fields where there may be missing + // indices. For example, it could be [40, 42], but in 90% of cases cases we have + // [40, 41, 42]. The latter is the case we are optimizing for, where for + // example `dex_field_idx` is 41, and we can just substract it with the + // first field index (40) and directly access the array with that index (1). + uint32_t index = dex_field_idx - GetField(0)->GetDexFieldIndex(); + if (index < num_fields) { + ArtField* field = GetField(index); + if (field->GetDexFieldIndex() == dex_field_idx) { + return field; + } + } else { + index = num_fields; + } + // If there is a field, it's down the array. The array is ordered by field + // index, so we know we can stop the search if `dex_field_idx` is greater + // than the current field's index. + for (; index > 0; --index) { + ArtField* field = GetField(index - 1); + if (field->GetDexFieldIndex() == dex_field_idx) { + return field; + } else if (field->GetDexFieldIndex() < dex_field_idx) { + break; } } } -- cgit v1.2.3-59-g8ed1b