From c88ac6fbf83ce707eb2f7bd28834aa271d82fedf Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 16 Sep 2024 15:55:39 +0200 Subject: [PATCH] Improve adaptive converter caching --- .../Resources/Adaptive/AdaptiveConverter.fs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs b/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs index 2673eb63..6af0b904 100644 --- a/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs +++ b/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs @@ -4,6 +4,7 @@ open Aardvark.Base open System open System.Reflection +open System.Collections.Concurrent open FSharp.Data.Adaptive [] @@ -45,22 +46,24 @@ module AdaptivePrimitiveValueConverterExtensions = member x.ConvertUntyped(value : IAdaptiveValue) = x.Convert(value) member x.Convert(array : aval) = x.Convert(array) - let private staticInstanceCache = Dict() - let private getStaticInstance (t : Type) : 'T = - lock staticInstanceCache (fun () -> - staticInstanceCache.GetOrCreate(t, fun t -> - let p = t.GetProperty("Instance", BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public) - p.GetValue(null) - ) |> unbox<'T> + let private converterCache = ConcurrentDictionary() + + let private getUntypedConverter (inputType: Type) (outputType: Type) : IAdaptiveConverter = + converterCache.GetOrAdd(struct (inputType, outputType), fun struct (inputType, outputType) -> + let tconv = typedefof>.MakeGenericType [| inputType; outputType |] + let prop = tconv.GetProperty(nameof(AdaptiveConverter.Instance), BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public) + prop.GetValue(null) |> unbox ) + let inline private getConverter<'T> (inputType: Type) : IAdaptiveConverter<'T> = + getUntypedConverter inputType typeof<'T> |> unbox> + let convertArray (inputElementType : Type) (array : aval) : aval<'T[]> = if inputElementType = typeof<'T> then array |> AdaptiveResource.mapNonAdaptive unbox else try - let tconv = typedefof>.MakeGenericType [| inputElementType; typeof<'T> |] - let converter : IAdaptiveConverter<'T> = tconv |> getStaticInstance + let converter = getConverter<'T> inputElementType converter.Convert(array) with | InvalidConversion exn -> raise exn @@ -71,8 +74,7 @@ module AdaptivePrimitiveValueConverterExtensions = value else try - let tconv = typedefof>.MakeGenericType [| inputType; outputType |] - let converter : IAdaptiveConverter = tconv |> getStaticInstance + let converter = getUntypedConverter inputType outputType converter.ConvertUntyped(value) with | InvalidConversion exn -> raise exn @@ -83,8 +85,7 @@ module AdaptivePrimitiveValueConverterExtensions = unbox value else try - let tconv = typedefof>.MakeGenericType [| inputType; typeof<'T> |] - let converter : IAdaptiveConverter<'T> = tconv |> getStaticInstance + let converter = getConverter<'T> inputType converter.Convert(value) with | InvalidConversion exn -> raise exn \ No newline at end of file