libandroidfw: use map for more efficient indexOfString()
Bug: 249320624 There number of calls to ResStringPool::indexOfString() is very high due to many calls to Resources.getIdentifier() in JAVA code. This is used to get the resource ID (a 32-bit integer) by its resource name (a string). One example pprof trace is at: https://pprof.corp.google.com/?id=9b9b377bf52bdeb972c6ad154acf3902 This happens to the key string pool in a package, which is normally encoded in UTF-8, unsorted. The call to indexOfString() ends up going through the whole key string pool and do a per string comparison til the string is found. For some large applications, the key string pool could have > 10k+ strings, which results in an excessive calling to string8At() or stringAt(). Although these calls are pretty quick, the excessive callings are not necessary and inefficient. There are a few ways to improve this: 1. sort the key strings so the current implementation ends up doing a binary search. However, for some reason, there is no code in aapt or aapt2 to support sorting and use the SORTED_FLAG. 2. or when needed, setup a std::map<StringPiece, size_t> to map the key string to its ID, and use the map for all subsequent calls to indexOfString() Here we chose the 2nd way with a few justifications: 1. std::map<> has a stable O(logN) lookup performance, and a key comparison doesn't involve comparing the whole key so it's both fast and relative stable. 2. by using StringPiece, we are not allocating memory if the string mapped doesn't need decoding, and StringPiece supports comparison. This CL reduces the number of calls into string8At() or stringAt() to the key string pool from 2m+ down to ~400k. See example pprof trace at: https://pprof.corp.google.com/?id=cb677fca932260b2dc7db64ee37c4b61 Change-Id: I77a0ef13daac6d8a5c63a681c52f8ab9712578ed
Loading
Please register or sign in to comment