Closed zyzhu closed 5 years ago
Hi,
you might want to have a look at ConcurrentDictionary.GetOrAdd(key, Func)
.
@kblohm Thanks for the tip. Code is simplified a lot. BTW, @dsyme and I initiated some discussions about general data science in f# in the following thread. Any inputs would be more than welcome. https://github.com/fslaborg/FsLab/issues/137
@zyzhu
Since you are using the ConcurrentDictionary.GetOrAdd(TKey, TValue)
overload and not ConcurrentDictionary.GetOrAdd(TKey, Func<TKey,TValue>)
, you are compiling your factory-lambda every single time you call the function, so your caching is not really doing anything now.
This should probably be something along the lines of:
let createTypedVector : _ -> seq<OptionalValue<obj>> -> _ =
let cache = ConcurrentDictionary<_, _ -> _>()
fun typ ->
let valueFactory t =
let par = Expression.Parameter(typeof<seq<OptionalValue<obj>>>)
let body = Expression.Call(createTypedVectorMi.MakeGenericMethod([| t |]), par)
Expression.Lambda<Func<seq<OptionalValue<obj>>, IVector>>(body, par).Compile().Invoke
cache.GetOrAdd(typ, Func<_,_>(valueFactory))
Also, while having a quick look at the module, there is a getCachedCompileProjection
aswell that is using a Dictionary to cache.
@kblohm Thanks for pointing it out. I added back trygetvalue so that cache shall work. I also changed getCachedCompileProjection
@zyzhu now you are not really solving the concurrency problem. Right now checking for the value and adding the value is not atomic, that is what GetOrAdd
is for.
@kblohm Clearly I'm a newbie on concurrent dictionary. I learned about valuefactory today and fixed it along your lines. A dumb question. Why the cache stays inside createTypedVector function? Isn't the cache re-initiated everytime a thread calls this function?
@dsyme Thanks for review. I've made above changes.
Attempt to fix issue 340 in pull 341. I simply replaced dictionary with concurrent dictionary. Ping @tpetricek for review. https://github.com/fslaborg/Deedle/pull/341