Task: Cut the rate instrument and leg read cost

Table of Contents

This page documents a task in the Decide the XML strategy for ORE documents story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

Name the cost inside read_rate_instrument and the leg append, remove what is avoidable, and record the instruction counts before and after.

2. Status

Field Value
State DONE
Parent story Decide the XML strategy for ORE documents
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-20

3. Acceptance

  • A line-level profile names the cost of read_rate_instrument and of the leg append
  • The largest avoidable cost of each is removed
  • The affected tests pass and the instruction counts are recorded

4. Plan

Read the callees of read_rate_instrument in the callgrind tree. Remove the largest avoidable cost. Then size the leg record and decide whether the leg append is worth a change.

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
Instructions of the import test before 1,646,496,411 valgrind --tool=callgrind ores.ore.core.tests import_portfolio_all_ore_example_files_can_be_parsed, run from the repository root f4f57e27ce
Instructions of the import test after 1,558,630,477 (-5.3 percent) same 8b168cfbb2
read_rate_instrument, 2,668 calls, before 157,286,395 callgrind_annotate --tree=calling --inclusive=yes f4f57e27ce
read_rate_instrument, after 76,872,989 same 8b168cfbb2
record_reader::own_text under append_legs, 8,431 calls, before 57,284,062 (6,800 per call) same f4f57e27ce
append_legs, after 44,376,073 (was 116,769,396) same 8b168cfbb2
Size of leg_data 8,784 bytes static_assert(sizeof(leg_data)==0) compile error 3e8f457d54
append_to for leg_data, 3,622 calls 48,050,849 (3.1 percent of the test), of which 31,880,844 is the zero fill callgrind_annotate 8b168cfbb2

6. Notes

  • Cause: a leg amount is a decimal field. own_text() formatted it as a string with to_string(), and the caller parsed it back with from_string(). The two are inverses, so the value did not change, but the format cost 6,800 instructions per call. The new record_reader::own_decimal() copies a decimal field and parses a text field. Five projections had the same helper. They all use own_decimal() now.
  • The leg record is not changed. leg_data is 8,784 bytes, and its zero fill is 2.0 percent of the test. Its large members are the leg kinds. They come from the legDataType substitution group in the schema, not from an xs:choice. The column rule of the generator takes only xs:choice children, so a column for the leg kinds needs a new rule for substitution members. That is a larger change than the saving justifies. A reserve would save about 16 million instructions of the vector growth, which is 1 percent.
  • If the leg zero fill matters later, extend column_members in generate_xml_bindings.py to substitution members. Leg kinds are 19.

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#3596 [ore] Read a decimal leaf without formatting it first

9. Review

Comment summary File Decision Notes
       

10. Result

The decimal round trip cost 6,800 instructions per leg amount. It is removed. read_rate_instrument falls from 157 to 77 million instructions, and the import test falls by 5.3 percent to 1,558,630,477. The leg record is left as it is. The ore core tests pass (378 cases, 475,410 assertions) and the benchmark gate passes.

Emacs 29.3 (Org mode 9.6.15)