javascript - 将较大的字节数组转换为字符串
问题描述
什么时候N
设置为125K
以下作品
let N = 125000
let x = [...Array(N)].map(( xx,i) => i)
let y = String.fromCodePoint(...x)
console.log(y.length)
当 N 设置为128K
相同的代码中断时:
未捕获的 RangeError:超出最大调用堆栈大小
这是一个常见的操作:实现转换的最佳方式是什么?
请注意,我确实看过这个相关的 Q&A 。https://stackoverflow.com/a/3195961/1056563 我们不应该依赖node.js
并且使用的方法fromCharCode.apply
也失败了。最后,这个答案已经有将近十年的历史了。
那么处理这种转换的最新高性能方法是什么?
解决方案
这个问题是因为实现对接受的参数数量有限制。当通过扩展运算符向函数提供太多参数(在本例中超过 ~128k)时,这会导致引发异常。String.fromCodePoint
相对有效地解决此问题的一种方法(尽管代码稍多)是跨多个调用批处理操作。这是我提出的实现,它解决了我认为与扩展性能有关的问题以及代理对的处理(这是不正确的:fromCodePoint
不关心代理,fromCharCode
在这种情况下更可取)。
let N = 500 * 1000;
let A = [...Array(N)].map((x,i) => i); // start with "an array".
function codePointsToString(cps) {
let rs = [];
let batch = 32767; // Supported 'all' browsers
for (let i = 0; i < cps.length; ){
let e = i + batch;
// Build batch section, defer to Array.join.
rs.push(String.fromCodePoint.apply(null, cps.slice(i, e)));
i = e;
}
return rs.join('');
}
var result = codePointsToString(A);
console.log(result.length);
另外,我想要一个奖杯。上面的代码应该在 O(n) 时间内运行并最小化分配的对象数量。不能保证这是“最佳”方法。批处理方法的一个好处,以及为什么包含(或传播调用)的成本,是对中间字符串apply
的调用显着减少。String.fromCodePoint
YMMV - 尤其是跨环境。
这是一个在线基准。所有测试都可以访问和使用由 500k 个元素组成的相同生成的“A”数组。
推荐阅读
- sql - Oracle SQL 加入和扩展
- angular - Angular,BsDatepicker 格式
- rally - 获取给定版本的 Rally 用户故事快照
- sql - 在 SQL Oracle 中逐行条件计数项目
- opengl - 几何着色器正在复制形状(处理中)
- node.js - 从 Kubernetes NGINX 入口控制器公开服务总是返回 502 Bad Gateway
- javascript - 如何使用 Firebase Functions 中的 firebase 实时数据库?(电报机器人)
- html - 用 html 消失内容
- redis - 重新连接后生菜会重新发送AUTH吗?
- typescript - 如何使用 JSDoc 传递泛型类型参数?