我有一个REST端点,它返回大型数组(100K+元素),对象的属性包含ISO格式的日期(比如2021-08T10:48:39.637Z),我需要将它们解析为日期类型。
我目前有这样的情况:
const res = await fetch(...);
const json = await res.json();
for (let x of json.arr) {
x.d = new Date(x.d);
}我担心这可能会导致一些不必要的缓慢,因为干扰了d隐藏类,也因为 V8 属性的类型更改(字符串=>日期)。。
我读过这里,更改属性类型会给V8内部优化带来混乱:
更改属性或元素类型通常会导致V8创建不同的HiddenClass,这会导致类型污染,从而阻止V8生成最佳代码。
另一种选择可能是将JSON.parse()与revival() param一起使用,这允许基于键名来解析值,但我不确定在这种情况下如何使用V8来处理内部元素,甚至与我目前正在做的事情有什么不同。
const json = JSON.parse(txt, (key, val) => {
if (key === "d") {
return new Date(val);
}
return val;
});另一种方法可能是重新映射从await res.json()返回的对象,如
const json = await res.json();
const objArr = json.map(x => ({ ...x, d: new Date(x.d) }));使用这种方法,我担心克隆100K+对象的开销,它们是否都有相同的V8隐藏类?
我不关心JSON.parse()本身的性能,只关心扰乱V8隐藏类或由于迄今为止属性类型更改而造成的一些内部优化。它是一个庞大的对象数组,性能对于这个WebApp非常重要,所以我想确保我没有犯任何重大错误。
考虑到V8优化,解析日期类型的最有效方法是什么?
发布于 2021-08-08 17:44:32
(这里是V8开发人员。)
这很好,只需编写有意义的代码,让引擎担心它的速度。你现在的方法没什么问题。
而且,如果事实证明,编写某些代码的最明显的方法是不尽如人意地运行,那么修复这一点将是我们的工作;我们不希望JavaScript开发人员不得不经过扭曲才能解决引擎缺陷。
和我现在做的有什么区别吗?
一般来说,要确保两种(或更多)方法中哪一种更好,以及是否存在差异,唯一的方法是实现这两种方法并进行度量。当您这样做时,一定要使用真实的数据,最好是您自己的完整生产应用程序,或者快照/模拟。使用几行代码减少的微基准通常会产生误导(也就是说:它们似乎告诉您的内容与您在整个应用程序中所看到的效果无关,甚至可能相反),因为大大简化场景通常会改变引擎在引擎罩下所做的决定。你可能会想,“但在我的整个应用中,我不会看到这么小的细节的影响”--好吧,如果是这样的话,那就是你的答案:这不重要。
https://stackoverflow.com/questions/68702234
复制相似问题