【问题标题】:How to generically solve the problem of generating incremental integer IDs in JavaScript如何通用解决在 JavaScript 中生成增量整数 ID 的问题
【发布时间】: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


【解决方案1】:

但是当你用完整数时会发生什么?

你不会的。曾经。

但如果 JS 可以达到每秒 1000 万次操作,[这需要] 大约 30 年。

没有太多要补充的。没有一台计算机可以在同一个程序上运行 30 年。同样在这个非常人为的示例中您只生成 id。在实际计算中,您可能会花费 1/10000 的时间来生成 id,因此 30 年变成了 300000 年。

你如何解决这个生成递增整数的问题,如果你达到 Number.MAX_SAFE_INTEGER,你会从头开始循环,

如果您“从头开始循环”,它们将不再是“增量”。您的一项要求无法满足。

如果您将 ID 的生成并行化,那么您可以更现实地(更快地)用完递增的整数。

没有。为了使 id 严格递增,您必须在这些并行代理之间共享一个计数器。并且只能通过同步访问共享内存,所以不会更快。

如果您仍然认为自己会用完 52 位,请使用 BigInts。或符号,具体取决于您的用例。

【讨论】:

  • 仍然没有解决问题,它把它推到更大的价值上。我想知道如何解决 this 问题,但它一直困扰着我 :)
  • 你正试图用高级语言解决一个不存在的低级问题。答案是你不能。接受。
  • 或者至少,它没有任何意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多