agentsclimarketplace

Crystal benchmarking

Skill dsisnero/crystal_forge/skills/crystal-benchmarking

A set of skills to help with Crystal development

Install
npx -y skills add dsisnero/crystal_forge --skill crystal-benchmarking

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Build or repair Crystal benchmark harnesses and use them to measure throughput, latency, concurrency scaling, and hotspot location with real numbers. Use whenever the user asks for benchmarks, speedup data, throughput comparisons, worker-count comparisons, concurrency validation, hotspot analysis, or says not to guess about performance.

SKILL.md

5.0 KB, 989 tokens by cl100k_base, as published. Nobody here has run it

Crystal Benchmarking

Use this skill when the question is not "how should this be structured?" but "what does the runtime actually do?".

This skill is specifically for:

  • proving whether a concurrency change improves throughput
  • comparing sequential vs bounded-concurrent vs async return paths
  • identifying the real hotspot before changing more code
  • measuring worker-count scaling such as x1, xN, or sequential baselines
  • separating return latency from deferred/background work latency

If the task is general optimization, also read crystal-performance. If the task is about concurrency architecture or channel/fiber correctness, also read crystal-concurrency.

What this skill is for

Benchmarking is a separate discipline from both optimization and concurrency design. A code path can be:

  • concurrent but slower
  • asynchronous at the API boundary but still throughput-neutral
  • structurally elegant but not a hotspot
  • flat in microbenchmarks and still valuable for tail latency

Do not infer wins from code structure alone.

Core rules

  1. Measure the real path, not a toy helper, unless the helper itself is the question.
  2. Always compare against a named baseline.
  3. Run at least 3 times and discard the cold run unless the cold path itself matters.
  4. Distinguish throughput from return latency.
  5. Distinguish concurrency from parallelism.
  6. Keep flat or regressed results; they are part of the outcome.
  7. If a benchmark takes too long to be useful, parameterize it instead of guessing.

Benchmark questions to answer

Every benchmark pass should explicitly answer one or more of:

  • Is this code actually a hotspot?
  • Does bounded concurrency help at all?
  • At what worker count does it flatten or regress?
  • Is the win in total throughput, return latency, or both?
  • Is the dominant cost file I/O, parsing, extraction, FFI, serialization, or cache persistence?

Standard comparison set

For concurrency-sensitive code, prefer this comparison matrix:

  • sequential
  • concurrent x1
  • concurrent xN
  • async return
  • async flush or background completion

Use only the rows that make sense for the path.

Examples:

  • file prep: sequential, x1, xN
  • discovery/extraction: sequential baseline, pipeline x1, pipeline xN
  • async cache write: return latency, flush latency

Harness design

Parameterize size

Benchmarks should be controllable with environment variables or arguments:

  • file count
  • payload size
  • worker count
  • run count
  • section selection

This lets you shrink the run to get signal quickly, then scale up the hot path.

Isolate sections

If one section dominates the run, make benchmark sections selectable so you can rerun only:

  • file I/O
  • search prep
  • discovery
  • extract graph
  • cache flush

Keep fixture generation deterministic

Use generated local fixtures where possible:

  • fixed file counts
  • fixed method/function counts
  • stable names
  • no network

Concurrency-specific guidance

File I/O

Do not assume concurrent file reads are a win. On fast local disks they are often flat or slightly worse. Measure before keeping that complexity.

Discovery and extraction

This is often where the real cost lives: parser setup, tree-sitter parse, query execution, AST walking, symbol extraction.

If file I/O is flat but discovery is slow, stop micro-optimizing readers and benchmark parser/extractor stages directly.

Async persistence

For cache or snapshot writes, measure two numbers:

  • how fast the caller returns
  • how long flush/background completion takes

If return latency improves materially and flush stays bounded, async persistence may still be worthwhile even when total work is unchanged.

CPU-bound work

If bounded fibers show only small gains on a CPU-heavy path, benchmark whether the bottleneck is actually parallelizable before reaching for ExecutionContext::Parallel.

Output format

Always report:

  • exact benchmark command
  • fixture size and worker count
  • baseline and comparison rows
  • average warm time and cold time
  • what the numbers imply
  • next action based on the data

Use direct conclusions such as:

  • "file I/O is not the hotspot"
  • "search prep is flat; do not optimize this next"
  • "discovery dominates runtime and current concurrency only buys ~12%"
  • "async cache improves return latency but not total work"

When to stop

Stop benchmarking and switch back to implementation when:

  • one hotspot clearly dominates
  • a proposed optimization target has measurable headroom
  • a concurrency feature is shown to be flat or regressive

At that point, the benchmark result becomes the gate for the next code change.

Gives 0 of the 12 instructions most performance cost skills give in 989 tokens

Counted across 803 of the 1,058 authors here whose files we hold, read 2026-08-06

  • keep skill files under 500 linesin 82 of 803, across 17 files
  • use imperative form in instructionsin 81 of 803, across 10 files
  • draft assertions while test runs are in progressin 75 of 803, across 9 files
  • create two to three realistic test promptsin 74 of 803, across 8 files
  • write skill descriptions to be pushyin 72 of 803, across 7 files
  • save test cases to evals jsonin 72 of 803, across 6 files
  • ask questions about edge cases and input formatsin 71 of 803, across 6 files
  • save timing data immediately when runs completein 70 of 803, across 5 files
  • include all trigger conditions in the skill descriptionin 69 of 803, across 3 files
  • launch all test runs in a single turnin 69 of 803, across 3 files
  • capture intent before writing a skillin 67 of 803, across 1 file
  • import directly instead of barrel filesin 52 of 803, across 15 files

Said here and by no other author read

  • measure the real code path
  • discard the cold run
  • distinguish throughput from return latency
  • keep flat or regressed results
  • parameterize benchmark size
  • make benchmark sections selectable

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.