Token导航 LogoToken导航TokenDH.com
研究检索external-serviceclawhub未标认证来源可访问clear审计通过

bookforge-profiling-driven-performance-optimizationbookforge 分析驱动的性能优化

Agent Skill

bookforge-profiling-driven-performance-optimization 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

4,304

周安装

183

GitHub Stars

公开资料未说明

下载量

1,508
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bookforge-profiling-driven-performance-optimization(bookforge 分析驱动的性能优化)
来源仓库:https://github.com/quochungto/bookforge-profiling-driven-performance-optimization
安装命令:
openclaw skills install bookforge-profiling-driven-performance-optimization
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install bookforge-profiling-driven-performance-optimization

简介

通过重构与分析驱动代码性能优化。bookforge-profiling-driven-performance-optimization 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

  • 适合已有良好架构基础后的精细化调优场景。
  • 先分解模块再定位热点,避免盲目优化。
  • 涉及代码修改,需确认开发环境与版本兼容性。
  • 建议配合测试用例保障优化前后功能一致性。

SKILL.md

name
profiling-driven-performance-optimization
description
Optimize code performance by first refactoring to a well-factored structure, then running a profiler to find actual hot spots, and applying targeted optimizations only where the profiler points — never by guessing. Use this skill when users report the program is too slow, before any performance work begins on an unfactored codebase, or after refactoring is complete and performance must now be tuned to acceptable levels.
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/refactoring/skills/profiling-driven-performance-optimization
metadata
{"openclaw":{"emoji":"⚡","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status
draft
source-books
title
Refactoring: Improving the Design of Existing Code
authors
["Martin Fowler"]
chapters
[2]
tags
[refactoring, performance, code-quality]
depends-on
[]
execution
tier
3
mode
hybrid
inputs
description
A working program or module that runs too slowly or consumes too much memory, with or without existing tests.
tools-required
[Read, Write, Bash]
tools-optional
[]
mcps-required
[]
environment
Working codebase with a profiler available for the language. Output: optimized code with before/after profiling data showing improvement at the identified hot spots.
discovery
goal
Reach performance that satisfies users by targeting only the small fraction of code that actually consumes most of the time, leaving the rest untouched.
tasks
audience
developers, engineers, performance engineers, anyone tasked with making a program faster or more memory-efficient
when_to_use
When a program's performance is unacceptable and optimization work is beginning, or when developers are tempted to optimize code speculatively before measuring
environment
Working codebase. A profiler must be available (see Context and Input Gathering). The code should have a test suite to protect against regressions during optimization.
quality
placeholder

Profiling-Driven Performance Optimization

When to Use

You are being asked to make a program faster or reduce its memory usage, and one of these is true:

  • Users or stakeholders have reported the program is too slow
  • Performance testing has produced unacceptable numbers
  • You are about to begin a performance optimization pass after feature work is complete
  • A developer is speculating about what might be slow and wants to optimize "obvious" bottlenecks before measuring

This skill applies to any context where performance matters but you are not operating under hard real-time constraints (heart pacemakers, flight control systems). For hard real-time systems, time-budgeting per component is appropriate — that is a different technique. For the vast majority of software — web services, data pipelines, desktop applications, CLIs, APIs, batch jobs — this profiling-based approach is the correct one.

The core insight (Fowler's principle): "The secret to fast software, in all but hard real-time contexts, is to write tunable software first and then to tune it for sufficient speed." Well-factored code is not just easier to read — it is easier to optimize, because profilers can pinpoint individual methods rather than tangled blocks.

Before starting, confirm you have:

  • A working program (it runs correctly)
  • A profiler available for the language and runtime
  • A representative workload or benchmark to run under the profiler
  • A test suite (strongly recommended) to catch regressions during optimization

Context and Input Gathering

The Three Approaches to Performance — Know Which One You Are Avoiding

Before beginning optimization work, establish which approach is being proposed and steer toward the correct one:

ApproachDescriptionWhen appropriate
Constant attentionEvery developer, all the time, keeps performance in mind and makes micro-optimizations during regular developmentAlmost never. Spreads optimization throughout the codebase, increases development cost, and makes code harder to change — with most of the effort going to code that is not actually slow.
Time budgetingDecompose the design into components; assign each a time/memory budget that must not be exceededHard real-time systems only (medical devices, avionics, embedded with strict latency guarantees). Overkill for ordinary software.
Profiling-basedBuild the program in a well-factored manner first; then enter a dedicated optimization stage driven entirely by profiler dataThe correct approach for nearly all software. This is what this skill implements.

If the developer is proposing constant attention ("I'll just be more careful about performance as I write code"), redirect them to the profiling-based approach. The 90/10 rule makes constant attention wasteful: most programs spend 90% of their time in 10% of the code. Optimizing the other 90% is effort that produces no user-visible improvement.

Required Context

  • The program or module: What is being optimized? Get a clear scope boundary — the whole application, a specific service, a batch processing path, a single module.
  • The performance complaint: What specifically is too slow or too large? "The report generation takes 4 minutes and users expect under 30 seconds." Concrete numbers matter — they define what "satisfies users" means at the end.
  • The workload: What inputs or usage patterns should be used when profiling? Profiling against unrepresentative inputs produces unrepresentative hot spots. Use real or realistic production-like data.
  • The profiler: Identify the profiler for the language and runtime in use. Common options:
Language / RuntimeProfilers
PythoncProfile, py-spy, line_profiler, memory_profiler
JavaScript / Node.jsV8 CPU profiler (built into Chrome DevTools, --prof flag), clinic.js
Java / JVMJProfiler, YourKit, async-profiler, JDK Flight Recorder
Gopprof (built in), go test -bench)
Rustperf, cargo flamegraph, criterion
Rubyrack-mini-profiler, stackprof, ruby-prof
C / C++gprof, Valgrind/Callgrind, perf, Instruments (macOS)
.NETdotTrace, PerfView, BenchmarkDotNet
GeneralFlamegraphs (Brendan Gregg's format, works across runtimes)
  • The current state of the codebase: Is it already well-factored? If not, the correct first step is to refactor before optimizing. See the "Precondition" step below.

Sufficiency Check

You are ready to begin optimization when:

  1. You know exactly what performance target must be met ("satisfies users")
  2. You have a representative workload to run under the profiler
  3. A profiler is installed and runnable
  4. The codebase is in a well-factored state (or you have a plan to get it there)

Process

Step 0 — Precondition: Ensure the Codebase Is Well-Factored

Before running the profiler for the first time, assess whether the code is already well-structured.

Why this step exists: Profiling unfactored code (long methods, mixed responsibilities, tangled logic) is less effective because the profiler reports time in large, coarse units. You cannot pinpoint which part of a 300-line method is slow — only that the whole method is slow. Well-factored code with fine-grained methods gives the profiler smaller targets to report on, which means your optimization targets are also smaller and more precise.

Additionally, well-factored code is faster to optimize: you can add performance-specific code (caches, lazy initialization, index structures) more quickly because the code is already modular. Fowler found that well-factored code "gives you more time to focus on performance" — not because it runs faster, but because you spend less time understanding it before changing it.

How to check:

  • Methods are small and do one thing
  • Classes have clear, single responsibilities
  • Logic is not duplicated across multiple places
  • External dependencies (I/O, network, database) are isolated in identifiable locations

If the codebase is not well-factored: Refactor first. Apply method-decomposition-refactoring, code-smell-diagnosis, or other refactoring skills before starting this optimization workflow. This is not lost time — it is what makes the optimization phase both faster and more effective.

If the codebase is already well-factored: Proceed to Step 1.


Step 1 — Establish a Baseline: Run the Profiler

Run the program under the profiler using a representative workload. Record the output in full before making any changes.

Why: You need a before-state to compare against. Without a baseline, you cannot tell whether an optimization improved performance, had no effect, or made things worse. The baseline also establishes the current hot spots — the specific methods or code paths the profiler identifies as consuming the most time or memory.

What to record:

  • Total elapsed time (wall-clock time) for the workload
  • Profiler output: which methods/functions are consuming the most cumulative time, the most self time, or the most memory
  • For memory profiling: which allocations are largest, where they are created

Save the baseline output to a file — do not rely on memory. Example:

# Python: profile to a file, then display top 20 hotspots
python -m cProfile -o baseline.prof my_script.py workload_input.csv
python -c "import pstats; p = pstats.Stats('baseline.prof'); p.sort_stats('cumulative'); p.print_stats(20)"

# Go: CPU profile
go test -cpuprofile=baseline.prof -bench=BenchmarkMyFunction ./...
go tool pprof -top baseline.prof

# Node.js: run with profiling flag, then analyze
node --prof my_script.js
node --prof-process isolate-*.log > baseline.txt

Identify the top hot spots: typically 3-5 methods/functions that together account for most of the time. These are your optimization targets. Everything else is not worth touching.


Step 2 — Select One Hot Spot to Optimize

From the profiler output, choose the single largest consumer of time or memory. Focus on one hot spot at a time.

Why: Focusing on one hot spot at a time maintains the connection between a change and its effect. If you optimize three things simultaneously and re-profile to find no improvement, you cannot tell which (if any) of the three changes was responsible. One change → one measurement.

How to select: Sort the profiler output by cumulative time (time spent in a function including all calls it makes). The function at the top of that list is the hot spot to address first — it has the most potential to improve the overall result.

If the top hot spot is infrastructure code you cannot change (a library, a system call), move to the next one down the list.


Step 3 — Understand the Hot Spot Before Changing It

Read the hot spot code carefully before applying any optimization.

Why: The profiler tells you *where* time is being spent; it does not tell you *why* or *what to do about it*. You need to understand the code before you can optimize it correctly. Common causes of hot spots:

CauseTypical fix
Repeated expensive computation with the same inputsCache the result (memoization)
Repeated object/memory allocation in a tight loopReuse objects, pre-allocate, use lazy initialization
Unnecessary I/O inside a loop (database calls, file reads)Batch the I/O, move it outside the loop, use connection pooling
Inefficient data structure for the access patternReplace with a more appropriate structure (e.g., list to set for membership tests)
Redundant work (computing the same derived value multiple times)Compute once, store the result
Excessive copying of large data structuresUse references, views, or generators instead

Do not guess — read the code, understand the data flow, identify the specific waste.


Step 4 — Apply One Optimization in a Small Step

Make the smallest possible change that addresses the identified cause. Do not refactor other parts of the hot spot while you are in it — stay focused on the performance change only.

Why small steps: Small changes are easier to revert. If the optimization does not produce improvement (which happens frequently — see Step 5), the cost of undoing it is low. Large, sweeping optimizations that do not help leave you with a large, sweeping revert.

Apply the change, then immediately:

  1. Compile (if the language requires it)
  2. Run the test suite — confirm no regressions were introduced
  3. Proceed to Step 5

Note on trade-offs: Performance optimizations often make code harder to understand. This is an accepted trade-off, but only at the hot spot — not throughout the codebase. Localized complexity in one well-identified method is manageable. Widespread micro-optimizations are not.


Step 5 — Re-Profile: Measure the Effect

Run the profiler again with the same workload and compare the output to the baseline.

Why: This is the critical decision gate. Performance intuition is unreliable. Experienced engineers routinely expect optimizations to help that do not — and sometimes make things slower. The profiler does not care about intuition.

Decision logic:

Run profiler with same workload as baseline
  |
  ├── Hot spot time decreased meaningfully?
  |     YES → Keep the change. Update baseline. Return to Step 2.
  |
  └── No meaningful improvement (or performance got worse)?
        → BACK OUT THE CHANGE immediately. Do not keep it.
          Return to Step 3 and reconsider the cause.

What counts as "meaningful improvement": If the profiler shows the target method is now faster, and the total elapsed time for the workload improved measurably, keep the change. If the numbers are essentially the same within noise, the optimization had no real effect — remove it. Code clarity costs were paid; performance gains were not received.

Why back out aggressively: Every optimization that does not help is a net negative — it adds complexity without benefit. Fowler is explicit: "If you haven't improved performance, you back out the change." The discipline to revert unsuccessful optimizations is what keeps the codebase from accumulating unexplained complexity.


Step 6 — Repeat Until Performance Satisfies Users

Return to Step 2. Select the next hot spot from the current profiler output (the hot spot landscape changes as you optimize — the second-largest consumer may have become the first).

Continue the loop:

Profile → Identify hot spot → Understand cause → Apply one change → Compile + test → Re-profile
  → Improved? Keep and continue.
  → Not improved? Revert and try differently.
  → Performance satisfies users? Stop.

Stop condition: Stop when the performance target established in Context and Input Gathering is met — not before, not after. Over-optimizing past the target produces diminishing returns and accumulates unnecessary complexity.

If you exhaust the hot spots without meeting the target: The remaining time may be in infrastructure (OS, runtime, network) outside your control, or the architecture itself may need to change. Escalate to architectural-level decisions (parallelism, caching layer, algorithmic change) — these are larger changes that warrant their own planning.


Key Principles

1. Never optimize without profiler data. "Programmers are very bad at guessing where the bottlenecks are." (McConnell, cited by Fowler.) The 90/10 rule means you will almost certainly guess wrong. Code that looks slow often is not; code that looks innocent is often the real bottleneck. Measurement is the only reliable guide.

2. Well-factored code is a precondition for effective optimization. Fine-grained methods give the profiler fine-grained targets. A 300-line method that the profiler marks as slow tells you very little. Three 20-line methods with clear names tell you exactly where to look. Refactoring before optimizing is not delay — it is what makes the optimization fast.

3. One change per measurement cycle. The discipline of one change → one profile run is what connects cause to effect. Without it, you accumulate changes you cannot attribute to specific improvements, and you cannot safely revert the ones that did not help.

4. Back out unsuccessful optimizations without hesitation. An optimization that produced no measurable improvement costs code clarity for no performance gain. It must be removed. This is not failure — it is the scientific method applied to software. You learned something: that was not the bottleneck.

5. Optimize only where the profiler points. Leaving the non-hot-spot code clean and unoptimized is correct behavior, not laziness. The 90% of code that is not a hot spot should remain readable, maintainable, and clear. Optimizing it wastes time and degrades code quality without improving user-visible performance.

6. "Satisfies users" is the target, not maximum possible speed. Stop when the performance target is met. Over-optimization past the requirement accumulates complexity for no user benefit.


Examples

Example 1: Payroll processing system (based on Fowler's Chrysler case study)

Situation: A payroll system was expected to take over 1,000 hours to run the full payroll. The team suspected complex business logic was the cause and had ideas about where to optimize.

What actually happened: A profiler was brought in before any changes were made. The profiler revealed the biggest consumer was not business logic — it was the repeated creation of 12,000-byte strings, three per output record, deep in the I/O framework. The strings were so large that the runtime's garbage collector could not handle them normally and was paging them to disk on every creation.

Fix 1: Cache a single 12,000-byte string rather than creating a new one for each record. This addressed most of the problem. Fix 2: Change the framework to write directly to a file stream, eliminating the large strings entirely.

After profiling again: The profiler found the next hot spots — smaller strings of 800 bytes, 500 bytes. Converting those to stream writes as well continued the improvement.

Result: The payroll that was expected to take over 1,000 hours ran in 40 hours at launch, then 18 hours, then 12 hours, then 9 hours as optimization continued.

Key lesson: The team's initial guesses about what was slow were completely wrong. The profiler pointed to something nobody had considered. The well-factored codebase also enabled a later optimization — adding multithreading — that took only three days to implement because the code was already modular.


Example 2: A data pipeline that is too slow

Situation: A data processing pipeline takes 8 minutes to process daily input. Users expect under 2 minutes.

Step 0 — Check factoring: Methods are small and clearly named. Ready to proceed.

Step 1 — Baseline profile:

cumulative time by function:
  process_records()       482s   (called once)
  validate_record()       431s   (called 50,000 times)
  lookup_category()       398s   (called 50,000 times)
  format_output()          49s   (called 50,000 times)
  write_batch()             2s   (called 200 times)

Step 2 — Hot spot: lookup_category() consuming 398s out of 482s total. Clear target.

Step 3 — Understand cause: Reading the code reveals lookup_category() makes a database query on every call. 50,000 queries × ~8ms each = 400 seconds.

Step 4 — Optimization: Load the entire category table into an in-memory dictionary at startup. Replace the per-record database call with a dictionary lookup.

Step 5 — Re-profile:

cumulative time by function:
  process_records()        89s
  validate_record()        52s   (now the hot spot)
  lookup_category()         1s   (resolved)
  format_output()          34s
  write_batch()             2s

Total: 89 seconds (down from 482). Improvement confirmed. Keep the change.

Continue: Next hot spot is validate_record() at 52s. Profile, understand, optimize, measure. Repeat.


Example 3: Recognizing and redirecting the constant attention anti-pattern

Situation: A developer says: "I'm going to be careful about performance as I write this new feature — I'll avoid creating unnecessary objects and think about efficiency at every step."

Correct response: Redirect. Point out that constant attention has two specific costs:

  1. It slows down feature development because the developer is making optimization decisions without knowing which code will actually be slow.
  2. The 90/10 rule means most of the code being "carefully" written is not a hot spot and will never be. The optimization effort is wasted.

Better approach: Write the feature in the clearest, most well-factored way. After it is working, if performance is unacceptable, run a profiler. The profiler will tell you exactly which 10% of the new code to look at. Optimize only that.


License

This skill is licensed under CC-BY-SA-4.0. Source: BookForge — Refactoring: Improving the Design of Existing Code by Martin Fowler.

Related BookForge Skills

  • refactoring-readiness-assessment — Assess whether code is ready to refactor before entering the optimization precondition
  • build-refactoring-test-suite — Build the test suite that protects against regressions during optimization steps
  • method-decomposition-refactoring — Decompose large methods to give the profiler finer-grained targets

Browse more BookForge skills: bookforge-skills

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

90.04%
按下载量换算1,358

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

external-service

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills