小编Jop*_*ppy的帖子

在 Javascript 中制作函数的真实副本

我想在 Javascript 中定义两个函数(或类),它们具有完全相同的函数体,但它们是完全不同的对象。用例是我在主体中有一些通用逻辑,它是多态的(函数可以接受多种类型),但是通过只调用具有单一类型的函数,函数最终会更快,我假设因为 JIT 可以在每种情况下都采取更快乐的快速路径。

一种方法是简单地完全重复函数体:

function func1(x) { /* some body */ }
function func2(x) { /* some body */ }
Run Code Online (Sandbox Code Playgroud)

另一种以较少重复完成相同事情的方法是eval()

function func(x) { /* some body */ }
function factory() { return eval("(" + func.toString() + ")") }
let func1 = factory(), func2 = factory()
Run Code Online (Sandbox Code Playgroud)

eval()当然,缺点是任何其他工具(缩小器、优化器等)都完全出乎意料,并且有可能破坏我的代码,因此这不起作用。

在标准工具链(我使用 Typescript、esbuild 和 Vite)的范围内,是否有任何明智的方法可以做到这一点,而不使用技巧eval()或只是复制粘贴代码?我也有关于类定义的类似问题。


编辑:总结评论中发生的事情:

  1. 是的,性能差异是真实且可衡量的(尤其是在 Chrome 上,在 Firefox 和 Safari 上不那么明显),正如这个微基准所证明的那样。引发这个问题的真实程序要大得多,性能差异也更明显,我怀疑是因为 JIT 可以为单态函数做更多的内联,这会产生许多连锁反应。
  2. 返回闭包的明显解决方案不起作用,即
    function factory() { function func() { /* some body …
    Run Code Online (Sandbox Code Playgroud)

javascript ecmascript-6

18
推荐指数
2
解决办法
485
查看次数

编写高性能 Javascript 代码而不去优化

在用 Javascript 编写对大型数字数组进行操作的性能敏感代码时(想想线性代数包,对整数或浮点数进行操作),人们总是希望 JIT 尽可能多地提供帮助。大致意思是:

  1. 我们总是希望我们的数组被压缩 SMI(小整数)或压缩双精度数,这取决于我们是在进行整数还是浮点计算。
  2. 我们总是希望将相同类型的东西传递给函数,这样它们就不会被贴上“超态”标签和去优化。举例来说,我们总是希望被调用vec.add(x, y)xy被包装SMI阵列,或两者打包双阵列。
  3. 我们希望函数尽可能内联。

当一个人偏离这些情况时,就会发生突然而剧烈的性能下降。这可能由于各种无害的原因而发生:

  1. 您可以通过看似无害的操作将压缩的 SMI 数组转换为压缩的 Double 数组,例如相当于myArray.map(x => -x). 这实际上是“最好的”坏情况,因为压缩的 Double 数组仍然非常快。
  2. 您可以将打包数组转换为通用的打包数组,例如通过将数组映射到(意外地)返回nullor的函数上undefined。这种糟糕的情况很容易避免。
  3. 您可能会取消优化整个函数,例如vec.add()通过传入太多类型的东西并将其变成超态。如果您想进行“通用编程”,vec.add()则可能会发生这种情况,在您不注意类型的情况下(因此它会看到很多类型进入)以及在您想要获得最大性能的情况下使用(例如,它应该只接收盒装双打)。

我的问题更像是一个软问题,关于如何根据上述考虑编写高性能 Javascript 代码,同时仍然保持代码的美观和可读性。一些具体的子问题,以便您知道我想要什么样的答案:

  • 是否有一套关于如何在封装 SMI 阵列的世界中进行编程的指南(例如)?
  • 是否可以在 Javascript 中进行通用的高性能编程而不使用宏系统之类的东西来将诸如vec.add()调用站点之类的东西内联?
  • 鉴于诸如超态调用站点和去优化之类的事情,人们如何将高性能代码模块化为库?例如,如果我很高兴地A高速使用线性代数包,然后我导入一个B依赖于的包A,但B使用其他类型调用它并对其进行反优化,突然(没有更改我的代码)我的代码运行速度变慢。
  • 是否有任何易于使用的测量工具来检查 Javascript 引擎在内部使用类型做什么?

javascript jit v8 spidermonkey

12
推荐指数
1
解决办法
491
查看次数

将 DataArray 转换为 DataFrame 并保留坐标标签顺序

有没有一种简单的方法可以将 xarray DataArray 转换为 pandas DataFrame,我可以在其中指定将哪些维度转换为索引/列?例如,假设我有一个 DataArray

import xarray as xr
weather = xr.DataArray(
    name='weather',
    data=[['Sunny', 'Windy'], ['Rainy', 'Foggy']],
    dims=['date', 'time'],
    coords={
        'date': ['Thursday', 'Friday'],
        'time': ['Morning', 'Afternoon'],
    }
)
Run Code Online (Sandbox Code Playgroud)

结果是:

<xarray.DataArray 'weather' (date: 2, time: 2)>
array([['Sunny', 'Windy'],
       ['Rainy', 'Foggy']], dtype='<U5')
Coordinates:
  * date     (date) <U8 'Thursday' 'Friday'
  * time     (time) <U9 'Morning' 'Afternoon'
Run Code Online (Sandbox Code Playgroud)

假设我现在想将其移动到按日期索引的 pandas DataFrame,其中包含时间列。我可以通过使用.to_dataframe()然后.unstack()在生成的数据帧上来做到这一点:

<xarray.DataArray 'weather' (date: 2, time: 2)>
array([['Sunny', 'Windy'],
       ['Rainy', 'Foggy']], dtype='<U5')
Coordinates:
  * date     (date) <U8 'Thursday' 'Friday' …
Run Code Online (Sandbox Code Playgroud)

pandas python-xarray

6
推荐指数
1
解决办法
6928
查看次数