AssemblyScript 是不是支持函数数组?

Posted

技术标签:

【中文标题】AssemblyScript 是不是支持函数数组?【英文标题】:does AssemblyScript supports array of functions?AssemblyScript 是否支持函数数组? 【发布时间】:2021-04-16 19:50:39 【问题描述】:

这是我想转换为 AssemblyScript 的 js 代码

function make_func_array(size)
  function f1(w)
    w.val+=1
  
  function f2(w)
    w.val+=10
  
  var ans=[]
  for (let i=0;i<size;i++)
    ans.push(f1)
    ans.push(f2)    
  
  return ans


function run_ar(ar,val)
  var w=val
  for(let f of ar)
    f(w)
  
  return w.val


var ar=make_func_array(10)
var ans=run_ar(ar,3)
console.log('ans',ans)

它使用一组函数来执行一些基本的计算

我的问题是:AssemblyScript 是否支持函数数组?用 AssemblyScript 怎么写?

【问题讨论】:

【参考方案1】:

是的,这是可能的。只需要填充类型

declare function log(i: i32): void;

class W 
  val: i32;


function makeFnArr(size: i32): Array<(w: W) => void> 
  const f1 = (w: W): void => 
    w.val += 1;
  

  const f2 = (w: W): void => 
    w.val += 10;
  

  let ans: Array<(w: W) => void> = [];
  for (let i = 0; i < size; i++) 
    ans.push(f1);
    ans.push(f2);   
  

  return ans;


function runArr(arr: Array<(w: W) => void>, val: i32): i32 
  let w: W =  val ;
  for (let i = 0, len = arr.length; i < len; i++) 
    let fn = arr[i];
    fn(w);
  
  return w.val;


var arr = makeFnArr(10);
var ans = runArr(arr, 3);

log(ans);

AssemblySctipt playground

【讨论】:

非常感谢您提供如此完整的答案!。我在github.com/yigalirani/speed_test/blob/master/js/assembly/… 的基准程序中添加了这一点,目标是在上述计算中比较 JS 和 AS 的性能(以我的 XML Marker 程序中的标记器模块为模型)。结果可能会让你大吃一惊:JS 和 AS 的性能差不多,大约是 CPP 性能的四分之一 @yigal 我并不感到惊讶。 Wasm 和 JS 共享大量代码生成部分,这并不是调动 WebAssembly 全部潜力的最佳示例。关于与 C/C++ 的比较。大多数 WebAssembly 运行时仍然缺少一些重要的循环优化,例如循环展开:bugs.chromium.org/p/v8/issues/detail?id=11298。所以我猜未来 JS 和 native 之间的差距会越来越小 比较也不精确。 C++ 版本使用预分配数组:github.com/yigalirani/speed_test/blob/master/cspeed/…,而 AS 版本使用动态数组。为了进行适当的比较,C++ 应该使用没有保留构造函数的 std::vector,我猜也应该使用两个 push_back 调用)另一个差异:C++ 不使用盒装类,而 AS/JS 版本将“val”包装到类对象中【参考方案2】:

您可以通过编写例如将函数转换为usize 指针。 changetype&lt;usize&gt;(() =&gt; true);(这里的() =&gt; true 是一个返回true 的简单函数)。然后你可以创建一个usize的数组。

调用函数。使用changetype 再次将其转换回函数: changetype&lt;() =&gt; boolean&gt;(funcPointer)()

以下是使用 AssemblyScript 制作的合成器的示例:https://gist.github.com/petersalomonsen/5b795090ead4f192e7f5ee5dcdd17392#file-wasmsong2-mix-ts-L337

【讨论】:

谢谢,解决了一些小问题

以上是关于AssemblyScript 是不是支持函数数组?的主要内容,如果未能解决你的问题,请参考以下文章

三等号 (===) 在 AssemblyScript 中的行为是不是不同?

AssemblyScript:动态本地数组大小

在 AssemblyScript 中实例化数组的三种不同方法

使用 AssemblyScript 通过引用操作画布数据(类型化数组)

如何在 AssemblyScript / Near 中打印数组的长度?

优化的 AssemblyScript 仍然是 4K,用于简单的乘法