【发布时间】:2019-12-31 08:37:39
【问题描述】:
这几天我一直在考虑这个问题,想看看是否有一个通用的方法来编写这个函数,这样你就不必担心它会再次崩溃。也就是说,它尽可能地健壮,并且可以支持高效且有效地使用所有内存(在 JavaScript 中)。
所以问题是关于一个基本的事情。通常,当您在 JavaScript 中创建某种类型的对象时,您可能会给它们一个 ID。在浏览器中,例如对于虚拟 DOM 元素,您可能只需给它们一个全局唯一 ID (GUID) 并将其设置为递增整数。
GUID = 1
let a = createNode() // { id: 1 }
let b = createNode() // { id: 2 }
let c = createNode() // { id: 3 }
function createNode() {
return { id: GUID++ }
}
但是当你用完整数时会发生什么? Number.MAX_SAFE_INTEGER == 2⁵³ - 1。这显然是一个非常大的数字:9,007,199,254,740,991 可能是千万亿。数十亿亿。但是,如果 JS 可以达到每秒 1000 万次操作,可以随便说一下,那么达到这个数字大约需要 900,719,925s,或者 10416 天,或者大约 30 年。所以在这种情况下,如果你让你的计算机运行 30 年,它最终会耗尽递增的 ID。这将是一个很难找到的错误!!!
如果您将 ID 的生成并行化,那么您可以更实际地(更快地)用完递增的整数。假设您不想使用 GUID 方案。
鉴于计算机的内存限制,您只能创建一定数量的对象。在 JS 中,您可能无法创建超过几十亿。
但我的问题是,作为一个理论练习,你如何解决生成递增整数的问题,这样如果你达到Number.MAX_SAFE_INTEGER,你会从头开始循环,但不使用潜在的数十亿 (或者只是数百万)你已经“生活和绑定”。您必须使用哪种方案来实现它,以便您可以简单地循环遍历整数并始终知道您有一个可用的免费方案?
function getNextID() {
if (i++ > Number.MAX_SAFE_INTEGER) {
return i = 0
} else {
return i
}
}
随机notes:
整体速度最快的是 Chrome 11(每十亿次迭代不到 2 秒,或者每次迭代最多 4 个 CPU 周期);最慢的是 IE8(每十亿次迭代大约需要 55 秒,或者每次迭代超过 100 个 CPU 周期)。
基本上,这个问题源于这样一个事实,即我们典型的“实用”解决方案将在遇到Number.MAX_SAFE_INTEGER 的超级边缘情况下崩溃,这很难测试。我想知道一些你可以解决这个问题的方法,而不仅仅是以某种方式出错。
【问题讨论】:
-
为什么不只使用 GUID?发生碰撞的几率非常低。
-
因为对于粒子系统和高强度游戏,GUID 的生成速度比增量 ID 慢。
-
啊,明白了。我不确定有这个限制。
-
我会使用字符串而不是数字。
-
@CertainPerformance 只是将问题推到更大的范围。
标签: javascript performance optimization integer