-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize inserts using reserve() and micro optimizations #3257
Conversation
for (int i = 0; i < chunks.size(); i++) { | ||
GraphLayout::GraphBlock gbChunk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you have profiling results proving that this is performance critical to reuse this block, I recommend keeping the declaration where it was. Reusing it without clearly reinitializing everything has risk of getting some old values from previous iterations, if not now, then as rest of code changes. std::move
at the end isn't reliable way for ensuring the state of reused block afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karliss, will this code fix this situation?
// add the blocks for the chunks
GraphLayout::GraphBlock gbChunk;
gbChunk.edges.reserve(chunks.size() * 2);
for (int i = 0; i < chunks.size(); i++) {
gbChunk.entry = chunks[i].addr;
gbChunk.edges.emplace_back(chunks[i].fd);
gbChunk.edges.emplace_back(chunks[i].bk);
// if last chunk and there is message then show it in the chunk
if (i == chunks.size() - 1 && heapBin->message) {
chunks[i].content += "\n" + QString(heapBin->message);
}
addBlock(gbChunk, chunks[i].content, chunks[i].addr);
memset(&gbChunk, 0, sizeof(gbChunk));
}
for (int i = 0; i < chunks.size(); i++) { | ||
GraphLayout::GraphBlock gbChunk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same ideas as previous comment about block reuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question as above.
@@ -126,8 +127,9 @@ void HeapBinsGraphView::display_double_linked_list(QVector<GraphHeapChunk> chunk | |||
addBlock(gbBin, content, heapBin->addr); | |||
|
|||
// add the blocks for the chunks | |||
GraphLayout::GraphBlock gbChunk; | |||
gbChunk.edges.reserve(chunks.size() * 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this is a pesimization not an optimization. No block will have that many edges.
And since you are both reusing the block and later moving it away, the reserving here is at best useless, and in the worst case if move doesn't succeed you will have overall reserved O(n^2) memory for a list.
Knowing that there are always two edges might as well do something like
gbChunk.edges = {
GraphEdge(chunks[i].fd),
GraphEdge(chunks[i].bk)
};
@@ -282,6 +282,7 @@ void DisassemblerGraphView::loadCurrentGraph() | |||
|
|||
auto vecVisitor = CutterPVector<RzAnalysisDisasmText>(vec.get()); | |||
auto iter = vecVisitor.begin(); | |||
db.instrs.reserve(vecVisitor.end() - iter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since iter is begin, wouldn't it be clearer to query the vector size directly? The first idea I get end - iter
that there is something more complicated going on, when what you actually need is vector size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, you're absolutely right, for some reason I tried find size through iterators.
If you actually want to improve the performance of big binary file analysis please do some profiling first. Blindly applying microptimizations in places that are not part of bottleneck, just makes the code harder to maintain with low chance giving perceivable improvement. I would guess that most of these changes are not anywhere near being the bottleneck. Feel free to prove me wrong with actual numbers. Since you already made the changes, assuming you fix the things I asked, I won't reject this. But that is not good approach for making meaningful optimization. |
Hello, your project is a really good replacement IDA Pro, and I am ready sacrifice time for profiling and showing more detailed information with benchmarks tests for each use reserve() function, a week is enough for me. |
@GermanAizek as Cutter uses Rizin as the backend, high chances that most of the performance bottlenecks would come from it. If you really want to help to speed up the project, I recommend checking the "optimization" label in the corresponding repository: https://github.com/rizinorg/rizin/labels/optimization Moreover, if you have a concrete cases in mind, profiling Rizin on them would provide better, more narrow window into the places what could be improved, in file format parsing or various analysis steps. |
@XVilka As soon as I'm done with this PR, I'll look at label in rizin. |
Detailed description
@XVilka this will also be needed since project focus on speedup big binary file analysis, later I will look for more similar places where I can apply similar methods speed exec optimization.