- String binary search does 1 less string comparison
- Identifier linear scan on large attribute list is switched to string binary search
Details
- Reviewers
rriddle - Commits
- rG2125eb3446d3: [mlir][core] Slightly improved attribute lookup
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
305–311 | I was going to add it to DictionaryAttr but since that's tied up in ODS I didn't bother... |
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
260–264 | ||
271–273 | Is the bool return important? What is the performance if you just return end() if the name isn't found? | |
274–275 | Just use ptrdiff_t. | |
280 | Spell out auto here. | |
295 | Drop the 16, it could change. Prefer being somewhat ambiguous on exact numbers of heuristics in comments. |
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
271–273 | For a linear search, the only gain is that you skip one extra it == end() check. For a binary search, it's important to know whether the attribute was actually found, because, if not, then it will be the sorted insertion point. If just end() was returned:
|
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
271–273 | And if the attribute was actually found (with a StringRef lookup) then it->first == name will compare the entire string (think operand_segment_sizes...) |
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
271–273 | Why would the binary search be different? Wouldn't we just return end in all of the cases where you currently return false, and the current iterator whenever you return true? |
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
271–273 | Case 1: attribute is found. Returning just an iterator: c++ auto it = findAttrSorted(begin(), end(), name); return it == end() ? Attribute() : it->second; // vs auto it = findAttrSorted(begin(), end(), name); return it.second ? it.first->second : Attribute(); All that happens is that the == end() check is skipped, which isn't much, but: Case 2: setting an attribute c++ auto it = findAttrSorted(begin(), end(), name); // a: attribute is found if (it != end()) { it->second = value; return; } // b: attribute is not found, where should the attribute be inserted? it = llvm::lower_bound(begin(), end(), name); // re-search the list attrs.insert(it, {name, value}); // vs auto it = findAttrSorted(begin(), end(), name); if (it.second) { it.first->second = value; return; } // it.first will be the sorted insertion point attrs.insert(it.first, {name, value}); // vs lower_bound auto it = llvm::lower_bound(begin(), end(), name); if (it != end() && it->first == name) { // re-compare the whole string (if found) it->second = value; return; } attrs.insert(it, {name, value}); Essentially, the bool contains the result of it->first == name so that it doesn't have to be re-checked. |
mlir/include/mlir/IR/OperationSupport.h | ||
---|---|---|
271–273 | Right, I missed where this was being used for insertion. |
mlir/lib/IR/OperationSupport.cpp | ||
---|---|---|
119–122 | Since this one is set(Identifier, Attribute), the identifier lookup doesn't return the sorted insertion point (either end() or the found attribute). You can either:
I chose (2) because that was the previous behaviour of the function. |