From cd069fab3f858e706ca2add1db9b22f9632bde45 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 13 Jun 2026 21:31:53 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[performance=20improvement]?= =?UTF-8?q?=20Avoid=20deep=20clones=20during=20OpenAPI=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cloudesize67-cmd <237356855+cloudesize67-cmd@users.noreply.github.com> --- .jules/bolt.md | 3 +++ xdk-openapi/src/parser.rs | 49 ++++++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 00000000..02c58cc2 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2026-06-13 - Optimization: deserialize vs from_value +**Learning:** Performance memory pattern states that when deserializing from intermediate `serde_json::Value` or `serde_yaml::Value`, prefer `T::deserialize(&value)` over `from_value(value.clone())` to avoid expensive deep clones. However, when consuming the entire `Value` tree at the end of parsing, prefer `from_value(value)` (without cloning) so Serde can move strings and data directly without re-allocating. +**Action:** Identified redundant `clone()` calls in `xdk-openapi/src/parser.rs` when pre-loading OpenAPI components into the context from intermediate `serde_json::Value` / `serde_yaml::Value` trees. Patched code to use `T::deserialize(&value)` instead of `serde_json::from_value(value.clone())` and `serde_yaml::from_value(value.clone())` to avoid unnecessary deep clones of JSON/YAML subtrees. diff --git a/xdk-openapi/src/parser.rs b/xdk-openapi/src/parser.rs index 6a92b4e5..209efa1b 100644 --- a/xdk-openapi/src/parser.rs +++ b/xdk-openapi/src/parser.rs @@ -56,9 +56,9 @@ pub fn parse_yaml(yaml: &str) -> Result { if let Some(schemas) = components.get("schemas").and_then(|s| s.as_mapping()) { for (name, schema_val) in schemas { if let Some(name_str) = name.as_str() { - match serde_yaml::from_value::( - schema_val.clone(), - ) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::Schema::deserialize(schema_val) { Ok(schema) => ctx.add_schema(name_str.to_string(), schema), Err(e) => { eprintln!("Warning: Failed to parse schema {name_str}: {e}") @@ -70,9 +70,9 @@ pub fn parse_yaml(yaml: &str) -> Result { if let Some(parameters) = components.get("parameters").and_then(|p| p.as_mapping()) { for (name, param_val) in parameters { if let Some(name_str) = name.as_str() { - match serde_yaml::from_value::( - param_val.clone(), - ) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::Parameter::deserialize(param_val) { Ok(param) => ctx.add_parameter(name_str.to_string(), param), Err(e) => { eprintln!("Warning: Failed to parse parameter {name_str}: {e}") @@ -84,7 +84,9 @@ pub fn parse_yaml(yaml: &str) -> Result { if let Some(responses) = components.get("responses").and_then(|r| r.as_mapping()) { for (name, resp_val) in responses { if let Some(name_str) = name.as_str() { - match serde_yaml::from_value::(resp_val.clone()) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::core::Response::deserialize(resp_val) { Ok(resp) => ctx.add_response(name_str.to_string(), resp), Err(e) => { eprintln!("Warning: Failed to parse response {name_str}: {e}") @@ -99,7 +101,9 @@ pub fn parse_yaml(yaml: &str) -> Result { { for (name, rb_val) in request_bodies { if let Some(name_str) = name.as_str() { - match serde_yaml::from_value::(rb_val.clone()) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::core::RequestBody::deserialize(rb_val) { Ok(rb) => ctx.add_request_body(name_str.to_string(), rb), Err(e) => { eprintln!("Warning: Failed to parse requestBody {name_str}: {e}") @@ -114,9 +118,9 @@ pub fn parse_yaml(yaml: &str) -> Result { { for (name, ss_val) in security_schemes { if let Some(name_str) = name.as_str() { - match serde_yaml::from_value::( - ss_val.clone(), - ) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::SecurityScheme::deserialize(ss_val) { Ok(ss) => ctx.add_security_scheme(name_str.to_string(), ss), Err(e) => { eprintln!("Warning: Failed to parse securityScheme {name_str}: {e}") @@ -211,7 +215,9 @@ pub fn parse_json(json: &str) -> Result { OpenApiContextGuard::with_context_mut(|ctx| { if let Some(schemas) = components.get("schemas").and_then(|s| s.as_object()) { for (name, schema_val) in schemas { - match serde_json::from_value::(schema_val.clone()) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::Schema::deserialize(schema_val) { Ok(schema) => ctx.add_schema(name.clone(), schema), Err(e) => eprintln!("Warning: Failed to parse schema {name}: {e}"), } @@ -219,8 +225,9 @@ pub fn parse_json(json: &str) -> Result { } if let Some(parameters) = components.get("parameters").and_then(|p| p.as_object()) { for (name, param_val) in parameters { - match serde_json::from_value::(param_val.clone()) - { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::Parameter::deserialize(param_val) { Ok(param) => ctx.add_parameter(name.clone(), param), Err(e) => eprintln!("Warning: Failed to parse parameter {name}: {e}"), } @@ -228,7 +235,9 @@ pub fn parse_json(json: &str) -> Result { } if let Some(responses) = components.get("responses").and_then(|r| r.as_object()) { for (name, resp_val) in responses { - match serde_json::from_value::(resp_val.clone()) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::core::Response::deserialize(resp_val) { Ok(resp) => ctx.add_response(name.clone(), resp), Err(e) => eprintln!("Warning: Failed to parse response {name}: {e}"), } @@ -239,7 +248,9 @@ pub fn parse_json(json: &str) -> Result { .and_then(|rb| rb.as_object()) { for (name, rb_val) in request_bodies { - match serde_json::from_value::(rb_val.clone()) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::core::RequestBody::deserialize(rb_val) { Ok(rb) => ctx.add_request_body(name.clone(), rb), Err(e) => eprintln!("Warning: Failed to parse requestBody {name}: {e}"), } @@ -250,9 +261,9 @@ pub fn parse_json(json: &str) -> Result { .and_then(|ss| ss.as_object()) { for (name, ss_val) in security_schemes { - match serde_json::from_value::( - ss_val.clone(), - ) { + use serde::Deserialize; + // Optimization: Use T::deserialize(&value) to avoid expensive deep clones of JSON/YAML values + match crate::components::SecurityScheme::deserialize(ss_val) { Ok(ss) => ctx.add_security_scheme(name.clone(), ss), Err(e) => { eprintln!("Warning: Failed to parse securityScheme {name}: {e}")