Skip to content

Conversation

@kamilkisiela
Copy link
Contributor

Follows the same pattern as the response projection. One string buffer we write to.

Follows the same pattern as the response projection. One string buffer
we write to.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @kamilkisiela, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the project_requires method to improve its efficiency by using a single string buffer for building the JSON output. This approach minimizes memory allocations and string concatenations, leading to better performance. The change aligns the method with the pattern used in response projection.

Highlights

  • Performance Improvement: The project_requires method is optimized to use a single string buffer for writing, reducing memory allocations and improving performance.
  • Code Structure: The project_requires method is split into project_requires and project_requires_mut to facilitate writing to a mutable string buffer.
  • JSON Serialization: The code now directly writes JSON primitives (null, bool, number, string) to the buffer, avoiding intermediate string conversions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

Federation Audit Results

188 tests  ±0   151 ✅  - 10   3s ⏱️ ±0s
 41 suites ±0     0 💤 ± 0 
 41 files   ±0    37 ❌ +10 

For more details on these failures, see this check.

Results for commit ecf9564. ± Comparison against base commit 042bf53.

@github-actions
Copy link

TestsPassed ☑️SkippedFailed ❌️Time ⏱
federation-audit | abstract-types.xml18 ran3 ✅15 ❌539ms
federation-audit | child-type-mismatch.xml4 ran1 ✅3 ❌122ms
federation-audit | circular-reference-interface.xml2 ran1 ✅1 ❌48ms
federation-audit | complex-entity-call.xml1 ran1 ✅81ms
federation-audit | corrupted-supergraph-node-id.xml10 ran8 ✅2 ❌135ms
federation-audit | enum-intersection.xml5 ran5 ✅65ms
federation-audit | fed1-external-extends-resolvable.xml1 ran1 ✅24ms
federation-audit | fed1-external-extends.xml4 ran4 ✅63ms
federation-audit | fed1-external-extension.xml4 ran4 ✅63ms
federation-audit | fed2-external-extends.xml4 ran4 ✅79ms
federation-audit | fed2-external-extension.xml4 ran4 ✅62ms
federation-audit | include-skip.xml4 ran4 ✅84ms
federation-audit | input-object-intersection.xml3 ran3 ✅34ms
federation-audit | interface-object-with-requires.xml7 ran3 ✅4 ❌130ms
federation-audit | keys-mashup.xml1 ran1 ✅46ms
federation-audit | mutations.xml4 ran4 ✅82ms
federation-audit | mysterious-external.xml2 ran2 ✅40ms
federation-audit | nested-provides.xml2 ran2 ✅33ms
federation-audit | node.xml1 ran1 ✅26ms
federation-audit | non-resolvable-interface-object.xml7 ran7 ✅83ms
federation-audit | null-keys.xml1 ran1 ❌35ms
federation-audit | override-type-interface.xml4 ran3 ✅1 ❌69ms
federation-audit | override-with-requires.xml4 ran4 ✅92ms
federation-audit | parent-entity-call-complex.xml1 ran1 ✅32ms
federation-audit | parent-entity-call.xml1 ran1 ✅38ms
federation-audit | provides-on-interface.xml2 ran2 ✅40ms
federation-audit | provides-on-union.xml2 ran1 ✅1 ❌44ms
federation-audit | requires-interface.xml5 ran5 ✅88ms
federation-audit | requires-requires.xml5 ran5 ✅107ms
federation-audit | requires-with-argument.xml5 ran3 ✅2 ❌109ms
federation-audit | requires-with-fragments.xml6 ran4 ✅2 ❌121ms
federation-audit | shared-root.xml2 ran2 ✅45ms
federation-audit | simple-entity-call.xml1 ran1 ✅23ms
federation-audit | simple-inaccessible.xml4 ran4 ✅52ms
federation-audit | simple-interface-object.xml13 ran8 ✅5 ❌208ms
federation-audit | simple-override.xml2 ran2 ✅37ms
federation-audit | simple-requires-provides.xml12 ran12 ✅170ms
federation-audit | typename.xml6 ran6 ✅100ms
federation-audit | unavailable-override.xml2 ran2 ✅34ms
federation-audit | union-interface-distributed.xml10 ran10 ✅103ms
federation-audit | union-intersection.xml12 ran12 ✅154ms

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The code changes improve the project_requires method by using a single string buffer to write to, following the same pattern as the response projection. This reduces memory allocations and improves performance. However, there are some areas where error handling and efficiency can be further improved.

Comment on lines +856 to +864
pub fn project_requires(
&self,
requires_selections: &Vec<SelectionItem>,
entity: &Value,
) -> String {
// Pre-allocate a buffer, but we can do it without I think
let mut buffer = String::with_capacity(1024);
self.project_requires_mut(requires_selections, entity, &mut buffer);
buffer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider making the buffer a field of the QueryPlanExecutionContext struct to avoid reallocating it for each call. This could improve performance by reusing the same buffer across multiple calls to project_requires. Also, the comment "Pre-allocate a buffer, but we can do it without I think" suggests that the initial capacity might not be necessary or optimal. Consider benchmarking with and without the initial capacity to determine the best approach.

        &self,
        requires_selections: &Vec<SelectionItem>,
        entity: &Value,
    ) -> String {
        self.project_requires_mut(requires_selections, entity, &mut self.buffer);
        self.buffer.clone()
    }

Comment on lines +921 to +927
// To avoid writing empty fields, we write to a temporary buffer first
let mut temp_buffer = String::new();
self.project_requires_mut(
&requires_selection.selections.items,
original,
&mut temp_buffer,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Creating a new String in each iteration can be inefficient. Consider using String::clear() on temp_buffer at the beginning of the loop to reuse the same buffer, or even better, use the main buffer directly with proper management of the first flag.

                    let original = entity_obj
                        .get(field_name)
                        .unwrap_or(entity_obj.get(response_key).unwrap_or(&Value::Null));

                    // To avoid writing empty fields, we write to a temporary buffer first
                    temp_buffer.clear();
                    self.project_requires_mut(
                        &requires_selection.selections.items,
                        original,
                        &mut temp_buffer,
                    );

@github-actions
Copy link

k6-benchmark results

     ✓ response code was 200
     ✓ no graphql errors
     ✓ valid response structure

     █ setup

     checks.........................: 100.00% ✓ 8298      ✗ 0   
     data_received..................: 245 MB  8.1 MB/s
     data_sent......................: 3.3 MB  108 kB/s
     http_req_blocked...............: avg=69.61µs  min=1.43µs  med=3µs      max=7.12ms   p(90)=4.67µs   p(95)=5.91µs  
     http_req_connecting............: avg=60.42µs  min=0s      med=0s       max=6.34ms   p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=109.24ms min=4.53ms  med=97.75ms  max=480.23ms p(90)=167.37ms p(95)=207.61ms
       { expected_response:true }...: avg=109.24ms min=4.53ms  med=97.75ms  max=480.23ms p(90)=167.37ms p(95)=207.61ms
     http_req_failed................: 0.00%   ✓ 0         ✗ 2786
     http_req_receiving.............: avg=955.39µs min=33.34µs med=53.18µs  max=90.98ms  p(90)=427.5µs  p(95)=1.11ms  
     http_req_sending...............: avg=440.04µs min=8.5µs   med=15.32µs  max=82.36ms  p(90)=38.78µs  p(95)=937.16µs
     http_req_tls_handshaking.......: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=107.84ms min=4.47ms  med=96.93ms  max=477.8ms  p(90)=165.96ms p(95)=204.28ms
     http_reqs......................: 2786    92.045042/s
     iteration_duration.............: avg=543.96ms min=99.85ms med=530.64ms max=1.03s    p(90)=662.89ms p(95)=717.56ms
     iterations.....................: 2766    91.384274/s
     vus............................: 50      min=50      max=50
     vus_max........................: 50      min=50      max=50

@ardatan ardatan merged commit 77bd1a3 into no-preserve-order Jun 27, 2025
12 checks passed
@ardatan ardatan deleted the kamil-project-requires-impr branch June 27, 2025 11:32
ardatan pushed a commit that referenced this pull request Jun 30, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 1, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 2, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 2, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 2, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 2, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 3, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 3, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 8, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 8, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 8, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 9, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 16, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 17, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 18, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
ardatan pushed a commit that referenced this pull request Jul 21, 2025
Follows the same pattern as the response projection. One string buffer
we write to.
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.

2 participants