资讯详情

es-toolkit 的 `percentile`(BigInt 版):用最近顺序位法精确计算 p90 延迟等百分位数

📅 2026/9/16 19:36:42 | 华诺云谱 👁 阅读
es-toolkit 的 `percentile`(BigInt 版):用最近顺序位法精确计算 p90 延迟等百分位数
es-toolkit 的percentileBigInt 版用最近顺序位法精确计算 p90 延迟等百分位数【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkitpercentile是 es-toolkit 专为BigInt提供的百分位数计算函数返回数组中位于指定百分位如 p50、p90的BigInt值。它采用最近顺序位法nearest-rank method结果永远是数组中已存在的值、绝不插值非常适合在延迟监控、数据分位统计等需要处理超出Number安全整数范围的场景。读完本文你将掌握percentile的完整 API、边界行为与底层实现原理并能直接将其接入自己的性能统计代码。函数总览与适用场景在 es-toolkit 中percentile的定义如下const value percentile(numbers, 90);它回答一个经典统计问题数据中有多少比例的值落在某个阈值之下。例如 p90 延迟的含义是90% 的请求延迟低于该值这正是percentile(latencies, 90)的语义。该函数的完整签名与位置见 percentile.ts。::: infopercentile仅供es-toolkit/bigint使用其设计初衷是避免与其他数值类型的同名函数产生潜在冲突。仓库中还存在面向普通number的版本见 src/math/percentile.ts两者按模块区分互不干扰。:::使用方式percentile(arr, percentile)函数接收两个参数arrreadonly bigint[]用于计算百分位的BigInt数组percentilenumber要查找的百分位取值在0到100之间含端点。函数内部会对数组的副本进行排序——原数组不会被修改——然后取出对应顺位的值import { percentile } from es-toolkit/bigint; const latencies [1n, 2n, 3n, 4n, 5n]; console.log(percentile(latencies, 50)); // 3n console.log(percentile(latencies, 90)); // 5n // 数组无需预先排序 console.log(percentile([30n, 10n, 20n], 50)); // 20n返回值返回bigint类型指定百分位对应的BigInt值且必然是该数组中已经存在的某个值。核心算法最近顺序位法Nearest-Rank Methodpercentile基于最近顺序位法实现因此它永远不会在两个值之间插值也就永远不会产生需要四舍五入的结果。对BigInt而言这一点尤为关键——BigInt没有小数部分任何中间值都无法表示。从源码看计算顺位的核心逻辑位于 percentile.tsconst sorted arr.slice().sort((a, b) (a b ? -1 : a b ? 1 : 0)); if (percentile 0) { return sorted[0]; } const index Math.ceil(sorted.length * (percentile / 100)) - 1; return sorted[index];这里有三个值得注意的实现细节先拷贝再排序arr.slice()生成新数组避免污染调用方的原始数据。这一行为同样被测试用例显式验证——percentile.spec.ts 断言调用后原数组[30n, 10n, 20n]保持不变。0百分位特判直接返回最小值sorted[0]100百分位则通过Math.ceil计算自然落到最大值无需额外分支。比较函数使用显式三分支(a b ? -1 : a b ? 1 : 0)这是BigInt与number排序差异的关键点——后面会详细说明。看几个具体边界示例import { percentile } from es-toolkit/bigint; // 1n 与 2n 的中点本应是 1.5但 BigInt 无法表达小数 // 于是返回最近顺序位的值。 console.log(percentile([1n, 2n], 50)); // 1n // 0 永远返回最小值100 永远返回最大值 console.log(percentile([5n, 1n, 3n], 0)); // 1n console.log(percentile([5n, 1n, 3n], 100)); // 5n参数类型百分位是number不是BigInt一个容易忽略的细节是percentile参数本身是介于0到100之间的普通number而非BigInt。原因在于百分位是一个百分比相对比例而不是被测量的量它天然是连续的小数值域用number表示最为自然。错误处理与异常边界percentile对非法输入有明确且严格的校验错误路径同样位于 percentile.tsif (Number.isNaN(Number(percentile))) { throw new Error(Expected percentile to be a number but got ${percentile}.); } if (percentile 0) { throw new Error(Expected percentile to be 0 but got ${percentile}.); } if (percentile 100) { throw new Error(Expected percentile to be 100 but got ${percentile}.); } if (arr.length 0) { throw new RangeError(Cannot compute the percentile of an empty array.); }对应地percentile为NaN时抛出Errorpercentile小于0时抛出Errorpercentile大于100时抛出Error数组为空时抛出RangeError因为没有任何BigInt可以返回。实际效果import { percentile } from es-toolkit/bigint; percentile([1n, 2n, 3n], 101); // Error: Expected percentile to be 100 but got 101. percentile([], 50); // RangeError: Cannot compute the percentile of an empty array.这些行为均被 percentile.spec.ts 中的测试用例逐条锁定包括负数、超界、NaN与空数组四类异常场景。为什么需要 BigInt 版本精度与Math的局限BigInt可以精确表示任意大的整数而Number只能安全表示±2^53 - 1范围内的整数。以同目录下的 max.ts 为例其注释中给出的例子极具说服力9007199254740993n与9007199254740992n这两个值Math.max根本无法区分而BigInt的比较则始终精确。当数据量或延迟数值超出安全整数范围时percentile的BigInt版本是唯一可靠的选择。另一个微妙之处在于排序比较。BigInt不能直接使用(a, b) a - b这类基于算术差的比较器会损失精度甚至报错因此源码中采用了(a b ? -1 : a b ? 1 : 0)的显式比较写法而同目录下 median.ts 的实现也采用了完全一致的排序模式这说明这是 bigint 模块统一的编码惯例。与同模块其他统计函数的配合percentile位于 es-toolkit 的 bigint 模块中同一入口 index.ts 还导出了median、medianBy、max、maxBy、min、minBy、sum、sumBy等统计函数可以组合出完整的大整数统计分析工具链。例如先用max获取峰值再用percentile计算 p50/p90/p99即可全面刻画延迟分布。总结percentileBigInt 版通过最近顺序位法在不插值、不取整、不改原数组的前提下为任意大小的整数数组提供精确的百分位查询。其核心实现仅十余行见 percentile.ts却覆盖了排序、边界特判与四类异常校验配合 percentile.spec.ts 的完整测试是一个小而精、可直接信赖的工具函数。当你需要处理超出安全整数范围的 p90 延迟或类似分位统计时import { percentile } from es-toolkit/bigint即可开箱即用。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。