Skip to content

perf(allocator/vec2): replace self.reserve(1) calls with self.grow_one() for better efficiency#9856

Merged
graphite-app[bot] merged 1 commit intomainfrom
03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency
May 3, 2025
Merged

perf(allocator/vec2): replace self.reserve(1) calls with self.grow_one() for better efficiency#9856
graphite-app[bot] merged 1 commit intomainfrom
03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency

Conversation

@Dunqing
Copy link
Member

@Dunqing Dunqing commented Mar 18, 2025

The places calling self.reserve(1) already checked len == self.buf.cap(), in order to avoid checking again in reserve, we should call grow_one instead which is a shortcut of grow_amortized(len, 1).

Copy link
Member Author

Dunqing commented Mar 18, 2025

@github-actions github-actions bot added the C-performance Category - Solution not expected to change functional behavior, only performance label Mar 18, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 18, 2025

CodSpeed Instrumentation Performance Report

Merging #9856 will not alter performance

Comparing 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency (04e0390) with main (7f2f247)

Summary

✅ 36 untouched benchmarks

@Dunqing
Copy link
Member Author

Dunqing commented Mar 18, 2025

Unbelievable 😢
image

EDIT: This unbelievable result is due to my mistake.

@Dunqing Dunqing mentioned this pull request Jan 18, 2026
12 tasks
@Dunqing Dunqing force-pushed the 03-18-feat_allocator_vec2_add_specialized_grow_one_method branch from a305372 to b9a6398 Compare March 18, 2025 08:36
@Dunqing Dunqing force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from 4dc483f to 9d1db26 Compare March 18, 2025 08:36
@Dunqing Dunqing force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from 9d1db26 to c94a0f0 Compare March 18, 2025 08:59
@Dunqing Dunqing force-pushed the 03-18-feat_allocator_vec2_add_specialized_grow_one_method branch from b9a6398 to 9968328 Compare March 18, 2025 08:59
@Dunqing Dunqing force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch 7 times, most recently from 83b077f to 43613e1 Compare March 18, 2025 16:35
@Dunqing Dunqing marked this pull request as draft March 19, 2025 02:49
@Dunqing
Copy link
Member Author

Dunqing commented Mar 19, 2025

I've noticed the current extend implementation will call the push method, extend is quite a common method for our scenario, so I think #[inline(never)] is a deoptimization. I decided to get #9881 done first and then continue this.

@Dunqing Dunqing force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from 149392c to 901e287 Compare April 30, 2025 02:39
@Dunqing Dunqing changed the base branch from graphite-base/9856 to 03-18-feat_allocator_vec2_add_specialized_grow_one_method April 30, 2025 02:39
@Dunqing Dunqing force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch 2 times, most recently from 44dd469 to aae3118 Compare April 30, 2025 05:20
graphite-app bot pushed a commit that referenced this pull request May 3, 2025
…marking reserve as `#[cold]` and `#[inline(never)]` (#10675)

I guess the performance regression reason is that the current implementation has more instructions than before. Here to use the lower of `size_hint` to reserve space, which is bloating the loop body. Also, the `for` loop is easier to optimize by the compiler.  `reserve` inside `extend` is rarely taken, so mark it as `#[cold]` and `#[inline(never)]`, which can reduce the instructions in `while` loop. We got a 3%-4% performance improvement in the `minfier`, but the transformer performance did not fully get back to before #10670.

Anyway, I think we can accept the less than 1% performance regression; this change can unblock us from pushing forward the `Vec` improvement; we will get it back in at the end of the stack! See #9856
@graphite-app graphite-app bot force-pushed the 03-18-feat_allocator_vec2_add_specialized_grow_one_method branch 2 times, most recently from cbd2cdb to 979432a Compare May 3, 2025 13:12
@graphite-app graphite-app bot force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from aae3118 to a703a01 Compare May 3, 2025 13:12
@overlookmotel overlookmotel added the 0-merge Merge with Graphite Merge Queue label May 3, 2025
Copy link
Member

overlookmotel commented May 3, 2025

Merge activity

@overlookmotel overlookmotel changed the base branch from 03-18-feat_allocator_vec2_add_specialized_grow_one_method to graphite-base/9856 May 3, 2025 14:45
graphite-app bot pushed a commit that referenced this pull request May 3, 2025
…_one()` for better efficiency (#9856)

The places calling `self.reserve(1)` already checked `len == self.buf.cap()`, in order to avoid checking again in `reserve`, we should call `grow_one` instead which is a shortcut of `grow_amortized(len, 1)`.
@graphite-app graphite-app bot force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from a703a01 to 8f5911f Compare May 3, 2025 14:54
@github-actions github-actions bot added A-linter Area - Linter A-cli Area - CLI A-editor Area - Editor and Language Server labels May 3, 2025
@graphite-app graphite-app bot changed the base branch from graphite-base/9856 to 03-18-feat_allocator_vec2_add_specialized_grow_one_method May 3, 2025 14:54
Base automatically changed from 03-18-feat_allocator_vec2_add_specialized_grow_one_method to main May 3, 2025 15:00
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label May 3, 2025
…_one()` for better efficiency (#9856)

The places calling `self.reserve(1)` already checked `len == self.buf.cap()`, in order to avoid checking again in `reserve`, we should call `grow_one` instead which is a shortcut of `grow_amortized(len, 1)`.
@overlookmotel overlookmotel force-pushed the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch from 8f5911f to 04e0390 Compare May 3, 2025 15:04
@overlookmotel overlookmotel added the 0-merge Merge with Graphite Merge Queue label May 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 3, 2025

Walkthrough

This change updates the memory growth strategy in a custom vector implementation. Specifically, within the Vec type, the insert and push methods now call self.buf.grow_one() to increase capacity by one when needed, instead of the previous approach using self.reserve(1). This delegates the responsibility for buffer growth directly to the underlying RawVec's grow_one method. Additionally, the grow_one method in RawVec has its attribute changed from #[inline(never)] to #[inline], accompanied by a comment explaining that inlining is preferred for frequent use cases in the parser. No changes were made to the signatures of public or exported entities.

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2f247 and 04e0390.

📒 Files selected for processing (2)
  • crates/oxc_allocator/src/vec2/mod.rs (2 hunks)
  • crates/oxc_allocator/src/vec2/raw_vec.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (16)
  • GitHub Check: Clippy
  • GitHub Check: Benchmark (formatter)
  • GitHub Check: Benchmark (codegen)
  • GitHub Check: Benchmark (minifier)
  • GitHub Check: Conformance
  • GitHub Check: Benchmark (semantic)
  • GitHub Check: Benchmark (isolated_declarations)
  • GitHub Check: Benchmark (transformer)
  • GitHub Check: Test wasm32-wasip1-threads
  • GitHub Check: Benchmark (parser)
  • GitHub Check: Test (macos-latest)
  • GitHub Check: Miri
  • GitHub Check: Build Linter Benchmark
  • GitHub Check: Test NAPI
  • GitHub Check: Benchmark (lexer)
  • GitHub Check: Test (ubuntu-latest)
🔇 Additional comments (3)
crates/oxc_allocator/src/vec2/raw_vec.rs (1)

440-443: Improvement to grow_one inlining strategy.

The change from #[inline(never)] to #[inline] is appropriate for this function since it's a common case in the parser. The added comment clearly explains the rationale behind deviating from the standard library's approach.

crates/oxc_allocator/src/vec2/mod.rs (2)

1238-1241: Optimization by directly calling grow_one.

This change improves efficiency by replacing self.reserve(1) with self.buf.grow_one(). Since the code already checks if len == self.buf.cap(), using grow_one() directly avoids redundant capacity checks that would happen inside the reserve method.


1567-1569: Optimization by directly calling grow_one.

Similar to the change in the insert method, this change replaces self.reserve(1) with self.buf.grow_one() to avoid redundant capacity checks when growing the vector by one element.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot merged commit 04e0390 into main May 3, 2025
26 checks passed
@graphite-app graphite-app bot deleted the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch May 3, 2025 15:10
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label May 3, 2025
@overlookmotel overlookmotel restored the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch May 3, 2025 16:23
@overlookmotel overlookmotel deleted the 03-18-perf_allocator_vec2_replace_self.reserve_1_calls_with_self.grow_one_for_better_efficiency branch May 3, 2025 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-cli Area - CLI A-editor Area - Editor and Language Server A-linter Area - Linter C-performance Category - Solution not expected to change functional behavior, only performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants