asm.js:面向未来的开发

asm.js是一种特殊的JavaScript子集,旨在提高代码执行速度,尤其适合高性能需求的场景如Web游戏。它不是新的编程语言,而是通过遵循一套严格规范使JS引擎能优化执行。文章介绍了asm.js的起源、性能优势、兼容性问题、生成asm.js代码的工具Emscripten,以及它如何与C++交互。虽然目前Safari对其支持不足,但asm.js展示了Web技术的潜力,预示着未来可能将更多语言编译为高性能的Web代码。
摘要由CSDN通过智能技术生成

这是一个可深可浅的话题,会先简单介绍一下什么是asm.js,看看它长什么样子,再来聊聊asm.js为什么能带来高性能,会有一些简单的对比,然后再从工程的角度讲讲兼容性,如何打包使用等等。水平有限,肯定讲不透,就当是抛装引玉吧。

What’s asm.js

还记得前段时间的“围棋杀手”AlphaGo吧,设想一下,如果两台AlphaGo相遇,会擦出些什么火花?同样的算法,在同样的机器上跑,会是什么样的结果?两只“阿尔法狗”我是抓不到了,倒是可以看看微软写的两个AI棋手对战DEMO:Asm.js Chess Battle

游戏说明:

On this page, we match two chess engines against one another. They are identical in nearly every detail, including source code! The only difference is that one has a flag set to be interpreted as asm.js, a specialized and strict JavaScript subset that allows JavaScript engines to employ specialized compilation to dramatically speed up execution.
Each turn is limited to 200ms – because the asm.js-optimized engine has a significant performance advantage, it can evaluate more moves per turn and has a substantially higher likelihood of victory. You can adjust the turn length and other variables in the demo to see how they affect the outcome of the game.

在这个页面中,我们设置两个象棋引擎进行对战。 这两个引擎在各个细节上几乎一样,包括源代码! 唯一的区别是,其中一个引擎设置了标志,让浏览器按照asm.js规范(一个特定、严格、允许JavaScript引擎使用专门的编译来显着加快执行的JavaScript子集)来解释。
每回合“思考”时间为0.2s - 因为源码被浏览器解析为asm.js的象棋引擎具有显着的性能优势,所以它在每回合可以进行更多评估,因此具有更高的获胜可能性。

微软-asm.js演示

正所谓天下武功,唯快不破。运行得更快,在每一回合评估的可能越多,越容易取胜。

值得注意的是:仅在对asm.js规范做了优化的浏览器上运行才能看到上面的结果,如果你是Safari,那么抱歉,遵循asm.js规范的代码说不定会更慢。关于兼容性下面马上会提到。

主角登场

由上面那个象棋对战的演示可以看到,即使在web上,我们仍有许多场景(例如web游戏等)对运行性能有着极高的要求。对于这种极高的要求,这里介绍一种解法:asm.js

asm.js不是一门新的语言,而是JavaScript的一个子集。由Mozilla于2013年提出,主要为了提升JS引擎执行代码的速度。通俗来说,同样是js代码,符合asm.js规范的代码对JS引擎更加友好,JS引擎在解释执行这些代码更加省心(例如不用进行变量类型推断了),也就更加快。

asm.js介绍

an extraordinarily optimizable, low-level subset of JavaScript
一个极度可优化的,面向底层的JavaScript子集。

如果上面的描述你还看得一头雾水的话,说不定你在下面官方的常见问题中能找到一些答案。

如果你想深入了解asm.js的规范或者说草案标准,推荐看官方草案

asm.js、js、C++

下面我们来看一下同一个算法(参考网上),三种不同的“语言”(其实只有C++和js)实现。

C++

// For x = 1 to infinity: 
// if x not divisible by any member of an initially empty list of primes, 
// add x to the list until we have 25,000
// 
// x从1递增到无穷,如果x不能整除list里的所有数,
// 那么将x添加到list,直到list中有25,000个数
#include <stdio.h>

class Primes {
 public:
  int getPrimeCount() const { return prime_count; }
  int getPrime(int i) const { return primes[i]; }
  void addPrime(int i) { primes[prime_count++] = i; }

  bool isDivisibe(int i, int by) { return (i % by) == 0; }

  bool isPrimeDivisible(int candidate) {
    for (int i = 1; i < prime_count; ++i) {
      if (isDivisibe(candidate, primes[i])) return true;
    }
    return false;
  }

 private:
  volatile int prime_count;
  volatile int primes[25000];
};

int main() {
  Primes p;
  int c = 1;
  while (p.getPrimeCount() < 25000) {
    if (!p.isPrimeDivisible(c)) {
      p.addPrime(c);
    }
    c++;
  }
  printf("%d\n", p.getPrime(p.getPrimeCount()-1));
}

js

// For x = 1 to infinity: 
// if x not divisible by any member of an initially empty list of primes, 
// add x to the list until we have 25,000
// 
// x从1递增到无穷,如果x不能整除list里的所有数,
// 那么将x添加到list,直到list中有25,000个数

// 开始打点
// console.log("start");
var startTime = new Date();

function Primes() {
   
  this.prime_count = 0;
  this.primes = new Array(25000);
  this.getPrimeCount = function() {
    return this.prime_count; }
  this.getPrime = function(i) {
    return this.primes[i]; }
  this.addPrime = function(i) {
   
    this.primes[this.prime_count++] = i;
  }

  this.isPrimeDivisible &
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值