如何在 Nim 中缓存具有不同参数的函数?
How to cache function with different arguments in Nim?
我正在使用缓慢的数据加载和计算,并且想缓存结果,所以下次它会更快。
示例 - 我们想要两个功能 1) 将货币转换为美元和 2) 计算 CPI 指数(消费者价格指数)。
echo to_usd("EUR", (2000, 1, 1), false) # => 0.846
echo to_cpi("USD", (2000, 1, 1)) # => 144.0
我想知道是否可以自动生成缓存代码,也许可以使用一些库?类似于:
proc to_usd_slow*(currency: string, time: TimeD): float =
1.0 # some slow calculations
proc to_usd* = cache(to_usd_slow)
我目前正在手动写入缓存,如下面的代码所示,playground:
import hashes, tables
proc autohash*[T: tuple|object](o: T): Hash =
for f in o.fields: result = result !& f.hash
type
TimeD = tuple[year, month, day: int]
PointM = tuple[time: TimeD, value: float]
# CPI - Consumer Price Index
proc to_cpi_slow(currency: string, time: TimeD, extrapolate: bool): float =
1.0 # some slow calculations
# Cached version ---------------------------------------------------------------
type ToCpiKey = (string, TimeD, bool)
proc hash(v: ToCpiKey): Hash = v.autohash
var to_cpi_cache = init_table[ToCpiKey, float]()
proc to_cpi*(currency: string, time: TimeD, extrapolate: bool): float =
let key: ToCpiKey = (currency, time, extrapolate)
if key notin to_cpi_cache:
to_cpi_cache[key] = to_cpi_slow(currency, time, extrapolate)
to_cpi_cache[key]
# Curency conversions ----------------------------------------------------------
proc to_usd_slow*(currency: string, time: TimeD): float =
1.0 # some slow calculations
type ToUsdMKey = (string, TimeD)
proc hash(v: ToUsdMKey): Hash = v.autohash
var to_usd_cache = init_table[ToUsdMKey, float]()
proc to_usd*(currency: string, time: TimeD): float =
let key: ToUsdMKey = (currency, time)
if not(key in to_usd_cache): to_usd_cache[key] = to_usd_slow(currency, time)
to_usd_cache[key]
# Usage ------------------------------------------------------------------------
echo to_cpi("USD", (2000, 1, 1), false)
echo to_usd("EUR", (2000, 1, 1))
可以使用宏生成缓存代码,很可能您想寻找 macro pragmas 来为您的函数编写必要的样板文件。
如果您想使用现有的库,您可能需要查看 memo 库。
我正在使用缓慢的数据加载和计算,并且想缓存结果,所以下次它会更快。
示例 - 我们想要两个功能 1) 将货币转换为美元和 2) 计算 CPI 指数(消费者价格指数)。
echo to_usd("EUR", (2000, 1, 1), false) # => 0.846
echo to_cpi("USD", (2000, 1, 1)) # => 144.0
我想知道是否可以自动生成缓存代码,也许可以使用一些库?类似于:
proc to_usd_slow*(currency: string, time: TimeD): float =
1.0 # some slow calculations
proc to_usd* = cache(to_usd_slow)
我目前正在手动写入缓存,如下面的代码所示,playground:
import hashes, tables
proc autohash*[T: tuple|object](o: T): Hash =
for f in o.fields: result = result !& f.hash
type
TimeD = tuple[year, month, day: int]
PointM = tuple[time: TimeD, value: float]
# CPI - Consumer Price Index
proc to_cpi_slow(currency: string, time: TimeD, extrapolate: bool): float =
1.0 # some slow calculations
# Cached version ---------------------------------------------------------------
type ToCpiKey = (string, TimeD, bool)
proc hash(v: ToCpiKey): Hash = v.autohash
var to_cpi_cache = init_table[ToCpiKey, float]()
proc to_cpi*(currency: string, time: TimeD, extrapolate: bool): float =
let key: ToCpiKey = (currency, time, extrapolate)
if key notin to_cpi_cache:
to_cpi_cache[key] = to_cpi_slow(currency, time, extrapolate)
to_cpi_cache[key]
# Curency conversions ----------------------------------------------------------
proc to_usd_slow*(currency: string, time: TimeD): float =
1.0 # some slow calculations
type ToUsdMKey = (string, TimeD)
proc hash(v: ToUsdMKey): Hash = v.autohash
var to_usd_cache = init_table[ToUsdMKey, float]()
proc to_usd*(currency: string, time: TimeD): float =
let key: ToUsdMKey = (currency, time)
if not(key in to_usd_cache): to_usd_cache[key] = to_usd_slow(currency, time)
to_usd_cache[key]
# Usage ------------------------------------------------------------------------
echo to_cpi("USD", (2000, 1, 1), false)
echo to_usd("EUR", (2000, 1, 1))
可以使用宏生成缓存代码,很可能您想寻找 macro pragmas 来为您的函数编写必要的样板文件。
如果您想使用现有的库,您可能需要查看 memo 库。