Skip to content
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

Closed
wants to merge 2 commits into from

Conversation

GermanAizek
Copy link
Contributor

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.

for (int i = 0; i < chunks.size(); i++) {
GraphLayout::GraphBlock gbChunk;
Copy link
Member

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.

Copy link
Contributor Author

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;
Copy link
Member

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.

Copy link
Contributor Author

@GermanAizek GermanAizek Nov 3, 2023

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);
Copy link
Member

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);
Copy link
Member

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.

Copy link
Contributor Author

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.

@karliss
Copy link
Member

karliss commented Oct 31, 2023

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.

@GermanAizek
Copy link
Contributor Author

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.

@XVilka
Copy link
Member

XVilka commented Nov 1, 2023

@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.

@GermanAizek
Copy link
Contributor Author

@XVilka As soon as I'm done with this PR, I'll look at label in rizin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants