You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何WebAssembly中sin函数性能远低于JavaScript?

关于WebAssembly与JavaScript三角函数性能差异的基准测试分析

我用Catch2运行了一组简单的基准测试,通过emscripten 3.1.37以-O3优化级别编译,测试代码如下:

BENCHMARK("cpp sin only")
{
    double sum = 1.0;
    for (int t = 0; t < 2000000; ++t) {
        sum += sin(double(t));
    }
    return sum;
};

#ifdef __EMSCRIPTEN__
    BENCHMARK("js sin only")
    {
        EM_ASM_DOUBLE({
            let sum = 1;
            for (let i = 0; i < 2000000; i++) {
                sum = sum + Math.sin(i);
            }
            return sum;
        });
    };
#endif

原本我认为JavaScript与WebAssembly的性能不会有显著差异,但实际结果相差悬殊:

chrome:
benchmark name                       samples       iterations    est run time
                                     mean          low mean      high mean
                                     std dev       low std dev   high std dev
-------------------------------------------------------------------------------
cpp sin only                                   100             1     7.93775 s 
                                        79.3856 ms     79.147 ms    79.7195 ms 
                                        1.43061 ms    1.10437 ms    1.97222 ms 
                                                                               
js sin only                                    100             1     2.21506 s 
                                        22.1354 ms    22.0064 ms       22.3 ms 
                                        742.138 us    614.746 us    901.128 us 

使用GCC 12.3.0原生编译时,耗时为24.2ms。

  • 我了解JavaScript所有数字均采用双精度浮点数,因此对比是公平的。若在C++版本中使用float类型,Chrome中耗时降至12ms,但仍慢于JavaScript(且精度更低),Firefox中则约为30ms。
  • 或许JavaScript使用了精度较低但速度更快的sin和sqrt实现?添加-fast-math并未提升双精度版本的性能。启用-fast-math的float版本在Chrome中与JavaScript速度相当,但在Firefox中仍约为30ms。
  • 是否是WebAssembly获得的优化器时间不足?这或许能解释其在Firefox中性能更差的原因,但emscripten难道不应负责大部分优化工作吗?
  • 会不会是Meltdown/Spectre防护机制导致的?

更新(应评论要求,补充更多基准测试结果)

  • g++12比clang15略快,但差距在10%以内
  • 各版本的sqrt性能几乎持平(此前示例中同时包含sqrt和sin)
  • 大部分时间消耗在sin函数上
  • 将迭代次数增加到200万时,JavaScript速度约为WebAssembly的4倍;增加到500万时,领先优势扩大至10倍。JavaScript仍与原生C++速度相当。
  • 注:该基准测试由Catch2执行100次,上述代码的总运行时间约为1秒。
  • 已验证并非JavaScript使用float类型导致差异,WebAssembly C++计算结果与JavaScript完全一致。
  • 使用123456789042+1000000作为输入时,gcc、clang原生版本、WebAssembly C++版本和JavaScript的运行时间均增加了约3-4倍(WebAssembly与JavaScript的相对性能保持不变)。
  • 参考代码和Chrome中的测试结果已留存。

更新2

在评论建议下,已向emscripten项目提交该问题。


内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:44:49