Skip to content

[Repo Assist] refactor: add save-based caching to GetField/GetEvent/GetNestedType; use Dictionary in ILNestedExportedTypesAndForwarders - #498

Merged
dsyme merged 2 commits into
masterfrom
repo-assist/improve-lookup-caching-20260405-3901128b137977e4
Apr 6, 2026
Merged

[Repo Assist] refactor: add save-based caching to GetField/GetEvent/GetNestedType; use Dictionary in ILNestedExportedTypesAndForwarders#498
dsyme merged 2 commits into
masterfrom
repo-assist/improve-lookup-caching-20260405-3901128b137977e4

Conversation

@github-actions

@github-actions github-actions Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

🤖 This is an automated PR from Repo Assist.

Summary

Two complementary consistency/performance improvements to ProvidedTypeDefinition and ILNestedExportedTypesAndForwarders.

1. save-based caching for GetField, GetEvent, GetNestedType

Before: these three overrides used Array.filter / Array.tryFind for O(n) linear scans on every call:

override this.GetField(name, bindingFlags) =
    let xs = this.GetFields bindingFlags |> Array.filter (fun m -> m.Name = name)
    if xs.Length > 0 then xs.[0] else null

After: they now use the same save-based dictionary cache that GetMethodImpl and GetPropertyImpl already use — building a name → member dictionary once per bindingFlags combination and doing O(1) lookups thereafter:

override this.GetField(name, bindingFlags) =
    let table =
        save (bindingFlags ||| BindingFlags.GetField) (fun () ->
            this.GetFields bindingFlags |> Seq.map (fun f -> f.Name, f) |> dict)
    match table.TryGetValue name with | true, f -> f | false, _ -> null

Discriminator bits chosen to avoid cache-key collisions with existing save calls:

Member Discriminator bit
GetMethodImpl BindingFlags.InvokeMethod (0x100) — existing
GetPropertyImpl BindingFlags.GetProperty (0x1000) — existing
GetField BindingFlags.GetField (0x400) — new
GetEvent BindingFlags.SetField (0x800) — new
GetNestedType BindingFlags.SetProperty (0x2000) — new

The stale //save ("field1", ...) / //save ("event1", ...) / //save ("nested1", ...) comments (from a previous refactor attempt) are also removed to reduce noise.

2. ILNestedExportedTypesAndForwarders: MapDictionary

Before: used a functional Map (balanced BST, O(log n) lookup) built via Array.fold:

let lmap = lazy ((Map.empty, larr.Force()) ||> Array.fold (fun m x -> m.Add(x.Name, x)))
member __.TryFindByName nm = lmap.Force().TryFind nm

After: consistent with the adjacent ILTypeDefs and ILExportedTypesAndForwarders types which already use Dictionary:

let lmap = lazy (
    let m = Dictionary()
    for x in larr.Force() do m.[x.Name] <- x
    m)
member __.TryFindByName nm = match lmap.Force().TryGetValue nm with true, v -> Some v | false, _ -> None

Test Status

All 126/126 tests pass (dotnet test tests/FSharp.TypeProviders.SDK.Tests.fsproj -c Release).

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@7ee2b60744abf71b985bead4599640f165edcd93

…use Dictionary in ILNestedExportedTypesAndForwarders

- ProvidedTypeDefinition.GetField, GetEvent, GetNestedType now use the
  same save()-based dictionary cache as GetMethodImpl and GetPropertyImpl,
  removing O(n) Array.filter/tryFind scans in favour of O(1) lookups.
  Also removes stale //save(...) comments left over from a previous
  refactor.
- ILNestedExportedTypesAndForwarders.TryFindByName now uses a Dictionary
  (O(1)) instead of a functional Map (O(log n)), consistent with the
  neighbouring ILTypeDefs and ILExportedTypesAndForwarders types.

126/126 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme
dsyme marked this pull request as ready for review April 6, 2026 21:30
@dsyme
dsyme merged commit b721d8d into master Apr 6, 2026
2 checks passed
github-actions Bot added a commit that referenced this pull request Apr 7, 2026
- Performance: O(1) convTypeRef assembly-name lookup (#493)
- Performance: O(N) ILMethodDefs index construction; lazy caches in TargetTypeDefinition (#497)
- Refactor: save-based caching for GetField/GetEvent/GetNestedType; Dictionary in ILNestedExportedTypesAndForwarders (#498)
- CI: NuGet and FAKE build caching (#495)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dsyme pushed a commit that referenced this pull request Apr 7, 2026
🤖 *This PR was created by [Repo
Assist](https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/24058266578).*

## Summary

Bumps the version to **8.5.0** by adding an entry to `RELEASE_NOTES.md`
covering all changes merged since 8.4.0:

- **Performance**: O(1) assembly-name dictionary lookup in `convTypeRef`
(#493)
- **Performance**: Avoid O(n²) allocations in `ILMethodDefs` name-index
construction; reuse lazy caches in `TargetTypeDefinition` for
`GetField`/`GetPropertyImpl`/`GetEvent` (#497)
- **Refactor**: `save`-based caching for
`GetField`/`GetEvent`/`GetNestedType` on `ProvidedTypeDefinition`;
`Dictionary` in `ILNestedExportedTypesAndForwarders` (#498)
- **CI**: NuGet and FAKE build caching (#495)

No code changes — RELEASE_NOTES.md only.

## Test Status

✅ 126/126 tests pass (`dotnet test
tests/FSharp.TypeProviders.SDK.Tests.fsproj -c Release`).




> Generated by 🌈 Repo Assist, see [workflow
run](https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/24058266578).
[Learn
more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md).
>
> To install this [agentic
workflow](https://github.com/githubnext/agentics/blob/7ee2b60744abf71b985bead4599640f165edcd93/workflows/repo-assist.md),
run
> ```
> gh aw add
githubnext/agentics@7ee2b60
> ```

<!-- gh-aw-agentic-workflow: Repo Assist, engine: copilot, model: auto,
id: 24058266578, workflow_id: repo-assist, run:
https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/24058266578
-->

<!-- gh-aw-workflow-id: repo-assist -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant