Skip to content

⚡ Bolt: [performance improvement] optimize RequestMetrics.to_dict() to bypass asdict overhead#6962

Open
ZeyuChen wants to merge 1 commit intodevelopfrom
bolt-optimize-request-metrics-to-dict-10413296569687171589
Open

⚡ Bolt: [performance improvement] optimize RequestMetrics.to_dict() to bypass asdict overhead#6962
ZeyuChen wants to merge 1 commit intodevelopfrom
bolt-optimize-request-metrics-to-dict-10413296569687171589

Conversation

@ZeyuChen
Copy link
Member

Motivation

The RequestMetrics class previously used dataclasses.asdict(self) within its to_dict() implementation. asdict() utilizes copy.deepcopy() internally, which inherently iterates recursively over all fields and applies expensive cloning logic even for primitive types. Since RequestMetrics objects are instantiated and serialized per-request, this deepcopy mechanism created a noticeable serialization overhead on the hot-path, particularly at high QPS.

Modifications

Replaced the dataclasses.asdict(self) call in RequestMetrics.to_dict() with a manually optimized field iteration.

  • Extracted field data via getattr().
  • Directly assigned primitives (int, float, str, bool, NoneType) without any copy overhead.
  • Shallowly mapped recursive iterations for list and dict components.
  • Defaulted to .to_dict() methods for internal nested dataclasses (like SpeculateMetrics) when available, reducing further dependency on generalized asdict() deepcopy loops.

Usage or Command

Standard deployment. The metrics API functions exactly the same but yields lower latency during serialization steps.

Accuracy Tests

Backward compatibility is maintained. Ran PYTHONPATH=. pytest tests/engine/test_request.py and full suite PYTHONPATH=. pytest tests/engine/ to verify tests pass and regressions are avoided.

Checklist

  • Run pnpm lint and pnpm test equivalent formatting & unit tests.
  • Explanatory comments exist.
  • No dependencies or architecture changes added.

PR created automatically by Jules for task 10413296569687171589 started by @ZeyuChen

Co-authored-by: ZeyuChen <1371212+ZeyuChen@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 21, 2026 14:43
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@paddle-bot
Copy link

paddle-bot bot commented Mar 21, 2026

Thanks for your contribution!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

该 PR 针对 fastdeploy/engine/request.py 中请求级指标 RequestMetrics 的序列化热点路径做性能优化,避免 dataclasses.asdict() 触发的递归 deepcopy 带来的开销,从而降低高 QPS 场景下的序列化延迟。

Changes:

  • RequestMetrics.to_dict()asdict(self) 改为手写字段遍历与类型分支序列化。
  • 引入 is_dataclass 用于识别嵌套 dataclass,并在存在 .to_dict() 时优先调用。
  • 新增 .jules/bolt.md 记录此次优化的经验与行动项。

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
fastdeploy/engine/request.py 重写 RequestMetrics.to_dict(),减少 asdict/deepcopy 在热路径上的开销
.jules/bolt.md 记录 dataclass 序列化优化的学习点与后续行动建议

import time
import traceback
from dataclasses import asdict, dataclass, fields
from dataclasses import asdict, dataclass, fields, is_dataclass
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

PR 标题目前为“⚡ Bolt: [performance improvement] ...”,不符合项目要求的“[CLASS]Title”格式。建议改为类似“[Perf] Optimize RequestMetrics.to_dict serialization”这样的格式,便于后续按类别检索与生成变更日志。

Copilot uses AI. Check for mistakes.
return {k: v for k, v in asdict(self).items()}

result = {}
for k in self.__dataclass_fields__:
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

to_dict() 里直接遍历 self.dataclass_fields 属于依赖 dataclasses 的内部实现细节,可读性和稳定性不如 dataclasses.fields(self/cls)。同一个类的 from_dict() 已经使用了 fields(cls);建议这里也用 fields(self) 并取 field.name 来迭代字段,保持一致性并减少对内部属性的依赖。

Suggested change
for k in self.__dataclass_fields__:
for field in fields(self):
k = field.name

Copilot uses AI. Check for mistakes.
Comment on lines +901 to +905
result = {}
for k in self.__dataclass_fields__:
v = getattr(self, k)
if type(v) in (int, float, str, bool, type(None)):
result[k] = v
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

RequestMetrics.to_dict() 的序列化逻辑已从 asdict() 改为自定义分支。当前 tests/engine 下虽覆盖了 Request/RequestOutput,但没有直接断言 RequestMetrics.to_dict() 的输出结构(尤其是 speculate_metrics 这类嵌套 dataclass)。建议补充单测覆盖:基础字段 + speculate_metrics=SpeculateMetrics(...) 时应输出纯 dict/list/primitive,避免序列化格式回归。

Copilot uses AI. Check for mistakes.
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