You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

J语言中Memoization(M.)缓存表受限致程序重复计算变慢

J语言M.缓存失效的解决办法

问题原因

J内置的M. memoization操作符缓存容量固定且无法由用户调整(从测试情况看默认容量为32)。当计算的参数数量超过这个阈值后,旧的缓存条目会被覆盖,导致后续需要重复计算已处理过的参数,缓存不仅没起到加速作用,还额外增加了管理开销,最终拖慢程序。

替代方案:手动实现缓存

既然内置缓存受限,我们可以自己维护缓存结构,完全控制缓存的存储逻辑,避免容量限制问题。以下是两种可行的实现方式:

1. 数组缓存(适合连续数字场景)

如果处理的是连续的数字序列,用数组作为缓存最节省空间且访问高效:

collatz =: (%&2)`(1+3&*)@.(2&|)
cache =: 0:`  NB. 缓存数组:索引对应数字,值对应步数,0表示未计算
countchain =: 3 : 0
  NB. 扩展缓存到足够长度,避免索引越界
  if. y > #cache do. cache =. cache , (y - #cache) $ 0 end.
  NB. 缓存命中直接返回
  if. v =. cache {~ y do. v return. end.
  echo 'xx ' , ": y
  if. 1=y do.
    res =. 1
  else.
    res =. 1 + countchain collatz y
  end.
  cache =. cache (y)} res  NB. 将结果存入缓存
  res
)

2. 字典缓存(适合稀疏数字场景)

如果处理的数字不连续,用字典存储缓存更节省空间:

collatz =: (%&2)`(1+3&*)@.(2&|)
cache =: (0 : 0) ''  NB. 初始化空字典,键为数字,值为步数
countchain =: 3 : 0
  NB. 缓存命中直接返回
  if. y e. keys cache do. cache { y return. end.
  echo 'xx ' , ": y
  if. 1=y do.
    res =. 1
  else.
    res =. 1 + countchain collatz y
  end.
  cache =. cache , (y;:res)  NB. 将结果存入字典
  res
)

这两种手动缓存方式完全由开发者控制缓存的生命周期和容量,不会出现M.的缓存溢出覆盖问题,能有效避免重复计算,大幅提升长序列计算的效率。

内容的提问来源于stack exchange,提问作者Abang F.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:06:18