假设服务器端JavaScript环境提供如下函数:
var parseIsoDuration = /... complex regex .../
function dateDiff(date, isoDurationStr){
var duration = parseIsoDuration.exec(isoDurationStr);
return timeLibrary.add(date, duration);
}
该功能将在数百个日期之外从外部调用,但大部分时间与ISO持续时间相同。因为RexExp解析不是一个廉价的操作,所以可以实现应用程序级缓存:
var parseIsoDuration = /... complex regex .../
var durationCache = {}
function dateDiff(date, isoDurationStr){
var duration;
if (durationCache[isoDurationStr] === undefined){
duration = parseIsoDuration.exec(isoDurationStr);
durationCache[isoDurationStr] = duration;
} else {
duration = durationCache[isoDurationStr];
}
return timeLibrary.add(date, duration);
}
问题:服务器可能连续运行一年,缓存对象永远不会超出范围。如果使用许多不同的ISO持续时间字符串调用该函数,则缓存将随着时间的推移而增长,并且永远不会减小其大小。
有没有办法告诉V8它可以清除" old"根据需要从缓存对象中输入(即已经变得太大)?或者至少在需要时完全清楚它? (解决方案可能取决于ES6 / 7功能)
ES6 WeakMaps听起来很有趣,但它们只接受对象作为键。在数组中包装字符串以使其成为对象将不起作用,因为再次执行该操作将导致不同的对象。我需要像Symbol(str)
这样的东西,但它会为两个相同的输入(Ref(str) === Ref(str)
)返回相同的参考。
编辑:实际上Symbol.for("str") === Symbol.for("str")
,但它不被接受为WeakMap密钥。
我还不确定在WeakMap的情况下,条目实际上是否会被垃圾收集 - 它可能或多或少立即生成,因为在将对象添加到WeakMap之后就没有对该对象的引用。所以双重号码
取消设置个别密钥时,需要额外的簿记,并且需要一些算法来确定合理的TTL。
是否有必要缓存RegExp结果?有一些内置缓存吗?对于文字表达式或仅通过构造函数创建,还是两者都创建?