Skip to content

[Low priority / 低优先级] perf(tui): profile append-aware Markdown source materialization #258

Description

@zhnt

中文

背景

PR #257 已解决长 active draft 的主要渲染性能问题:稳定 Markdown 语义组现在复用不可变 rendered segments,Working tick 和按键不再扫描或 materialize 旧 rendered rows,10,000 行场景也不再触发 4,096-entry block cache 的性能悬崖。

剩余边界

新 streaming chunk 到达时,source 层仍会对当前完整 draft 执行:

StreamingTextBuffer.logical_lines()
→ join 完整文本
→ expandtabs
→ append-prefix 检查
→ split 完整文本

这不会造成跳行、重复行或 Markdown 错误,也不影响已经提交的历史记录。它只可能在超长 active draft 或大量细碎 chunk 高频到达时,带来额外 CPU、临时字符串分配、GC 压力,以及 streaming 更新批量跳动。

优先级与启动条件

低优先级,暂不排期。 仅在满足以下任一条件时启动实现:

  • PR perf(tui): reuse stable streaming draft segments #257 合并后,真实终端中的长内容 streaming 仍有明显卡顿;
  • 分阶段 profiling 证明完整 source 物化已经成为主要耗时;
  • 更大规模(例如 50,000/100,000 行)成为实际支持场景。

潜在方向

让 Markdown streaming parser 根据现有 stable_end_line,直接从 StreamingTextBuffer 获取 mutable source tail,而不是每个新 chunk 都重建完整 source。完整文本只在 completion、unsafe fallback 或最终文本替换时物化。

不变量

  • 不改变 Markdown semantic-group 边界;
  • 不调整 Working tick 间隔;
  • 不调用 gc.collect(),不引入高低水位;
  • 每个检查点继续与 fresh full flat render 的 raw ANSI 行完全一致;
  • continuous list/table/fence 等无法安全增量化的场景允许回退 O(N)。

相关实现与性能数据:#257


English

Background

PR #257 fixed the dominant rendering cost for long active drafts. Stable Markdown semantic groups now reuse immutable rendered segments; Working ticks and composer input no longer scan or materialize old rendered rows; and the 10,000-line fixture no longer hits the 4,096-entry block-cache performance cliff.

Remaining boundary

When a new streaming chunk arrives, the source path still processes the complete active draft:

StreamingTextBuffer.logical_lines()
→ join the complete text
→ expandtabs
→ append-prefix validation
→ split the complete text

This does not cause missing, duplicated, or malformed Markdown rows, and it does not affect committed history. It may only add CPU time, temporary string allocations, GC pressure, and bursty streaming updates for extremely long active drafts or very frequent small chunks.

Priority and implementation gate

Low priority and not scheduled. Start implementation only if one of these conditions is met:

  • long streaming output remains visibly slow in a real terminal after PR perf(tui): reuse stable streaming draft segments #257;
  • phase profiling shows complete-source materialization has become a dominant cost;
  • substantially larger active drafts, such as 50,000 or 100,000 lines, become a real supported workload.

Possible direction

Use the existing stable_end_line to let the Markdown streaming parser request only the mutable source tail from StreamingTextBuffer. Materialize the complete text only for completion, unsafe fallback, or final-text replacement.

Invariants

  • do not change Markdown semantic-group boundaries;
  • do not change the Working tick interval;
  • do not add gc.collect() calls or watermarks;
  • keep raw ANSI output exactly equal to a fresh full flat render at every checkpoint;
  • allow continuous list/table/fence cases to fall back to O(N) when safe incremental processing cannot be proven.

Related implementation and performance evidence: #257

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions