From e806a5c5accd601e8ced9f37c6d2dbbba11df15c 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 | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs b/src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs index 2673eb63..c8de477c 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,21 @@ 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 getConverter<'T when 'T :> IAdaptiveConverter> (inputType: Type) (outputType: Type) : 'T = + converterCache.GetOrAdd((inputType, outputType), fun (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<'T> 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 : IAdaptiveConverter<'T> = getConverter inputElementType typeof<'T> converter.Convert(array) with | InvalidConversion exn -> raise exn @@ -71,8 +71,7 @@ module AdaptivePrimitiveValueConverterExtensions = value else try - let tconv = typedefof>.MakeGenericType [| inputType; outputType |] - let converter : IAdaptiveConverter = tconv |> getStaticInstance + let converter : IAdaptiveConverter = getConverter inputType outputType converter.ConvertUntyped(value) with | InvalidConversion exn -> raise exn @@ -83,8 +82,7 @@ module AdaptivePrimitiveValueConverterExtensions = unbox value else try - let tconv = typedefof>.MakeGenericType [| inputType; typeof<'T> |] - let converter : IAdaptiveConverter<'T> = tconv |> getStaticInstance + let converter : IAdaptiveConverter<'T> = getConverter inputType typeof<'T> converter.Convert(value) with | InvalidConversion exn -> raise exn \ No newline at end of file