Skip to content

tl v0.5

Choose a tag to compare

@IAFahim IAFahim released this 08 Sep 22:03

tl v0.5

tl v0.5 packages the reviewed runtime and generator work as Tl.Runtime 0.5.0 and Tl.Gen 0.5.0. This release does not redesign the current repository's input/result callback API. NuGet users upgrading from the previously published 0.1.0 packages must follow the migration steps below.

Production changes

  • Runtime WorkSlot layout is 24 bytes, down from 28 bytes by removing padding. This saves 14.3% per slot without changing its values, constructor, or public API.
  • Generated Forward and Backward playback use direction-specialized closed methods. In the matched Pulse comparison, five of six measured shapes improved; repeated single-tick throughput regressed by about 1.8%. A consumer using both directions materialized 45.9% more native code for the measured Advance bodies, so this remains an explicit time/code-size tradeoff.
  • The compile cache now keys exact source membership and contents together with generator/dependency identity. Exact hits preserve output timestamps; missing or modified outputs are repaired; removed declarations remove only unchanged files previously owned by that invocation; unowned and user-modified obsolete files are preserved.
  • Declaration discovery is stricter. It ignores unrelated Compile calls, accepts supported qualified Tl receivers and unsigned literals, rejects output-name collisions, reports unsupported option expressions, and no longer resolves an explicit author qualifier to an unrelated compatible method. Ambiguous and unsupported forms fail closed.
  • Tl.Gen packages the Roslyn assemblies its CLI needs, and build-tool references no longer inherit application NativeAOT publish properties.
  • Benchmark history identities now include job, parameters, runtime environment, and ISA. Duplicate or missing measurements fail collection, while near-zero estimates are archived below the comparison floor.
  • CI enforces the 200,000-byte src content-plus-path budget and verifies benchmark collection, generated-output identity, JIT parity, NativeAOT parity, the full solution, packages, and existing receipts.

Runtime authoring uses Timeline<TTrack,TClip>.Build(author).InMemory(). Each handle owns one native block and must be released exactly once with Timeline.Destroy(id) after playback has stopped. Build, registration, binding, and destruction require the documented synchronization. Playback reads immutable snapshots concurrently; destroying a handle during in-flight playback is invalid.

Migrating from NuGet 0.1.0

The only previously published versions of both packages are 0.1.0, so package consumers receive the v0.2–v0.5 changes together:

  • Split the former mutable ref TData consumer parameter into immutable in TInput and mutable ref TResult, following the v0.2 migration.
  • End runtime authoring with Build(...).InMemory(), retain the returned handle, and call Timeline.Destroy(id) once after all playback has stopped. Follow the native ownership and threading contract.
  • For build-time C# specialization, use the supported Build(...).Compile() declaration grammar and call the emitted static kernel described in the compiled-path guide.

Validation

The reviewed release gates include 46 core tests, 52 generator tests, 7 collector tests, interpreter/generated sample parity, published NativeAOT execution, package restoration and execution from a clean local feed/cache, repeat installed-package generation with a cache hit, and a source footprint of 186,154/200,000 bytes including paths.

Experimental consumer fusion

The release repository also records a separate research backend for the exact four-track, nineteen-clip Pulse timeline and one explicit ordered floating-point sum/subtract operation. The final repeat measured the tree/carry batch at 1.334 ns/tick sequential, 1.246 ns/tick repeated, and 7.291 ns/tick random; its sequential scalar entry point measured 2.524 ns/tick. All measured arms reported zero managed allocation after setup.

This experiment is not the general .Compile() backend. It does not analyze arbitrary consumer C#, change the public API, promise universal 2 ns performance, or establish Unity or Burst compatibility. Production generated playback still uses the general view/callback path and retained arrays.

Full details, exact benchmark tables, migration guidance, evidence, and remaining work are in the v0.5 document.