为了账号安全,请及时绑定邮箱和手机立即绑定

Blazor wasm 调用 javascript,传递大数组非常慢

Blazor wasm 调用 javascript,传递大数组非常慢

一只斗牛犬 2023-03-03 15:33:23
我有一个 blazor wasm 应用程序。因为我正在调用一个接收双精度数组的 javascript 函数。这非常慢,尤其是当数组很大时。有关测试,请参见以下代码:javascript(“test.js”):function testSumArray(array) {    var t0 = performance.now();    sumArray(array);    var t1 = performance.now();    console.log('From JS, time to sum: ' + (t1 - t0) / 1000 + ' s');}function sumArray(array) {    var i;    var s = 0;    for (i = 0; i < array.length; i++) {        s += array[i];    }    return s;}和 c# 代码 (index.razor):@page "/"@inject IJSRuntime JSRuntime;@using System.Text@using BlazorWasmOnlyTest.Shared<h1>Hello, world!</h1>Welcome to your new app.<div class="container">    <div class="row mb-2">        <div class="col">            <button class="btn btn-primary" @onclick="@TestInvokeJS">Test invoke js</button>        </div>    </div></div>@code {    private int _id;    private string _status = "";    private DataInputFileForm _dataInputFileForm;    private async void TestInvokeJS()    {        var n = 100000;        var array = new double[n];        for (int i = 0; i < n; i++)        {            array[i] = i;        }        var w = new System.Diagnostics.Stopwatch();        w.Start();        await JSRuntime.InvokeVoidAsync("testSumArray",array);        w.Stop();        Console.WriteLine($"C# time to invoke js and sum: {w.ElapsedMilliseconds/1000:F3} s");    }}并完成 - index.html:<!DOCTYPE html><html><head>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />    <title>BlazorWasmOnlyTest</title>    <base href="/" />    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />    <link href="css/app.css" rel="stylesheet" />    <script src="js/test.js"></script></head>运行一次会在我的机器上产生以下输出:从 JS,求和时间:0.0037800000282004476 sC# 调用 js 和总和的时间:7.000 秒这似乎是一个相当高的开销时间......有谁知道是否有办法加快这个速度(真正的功能做了我目前在 Blazor/C# 中不能做的事情 - 在 Leaflet 中更新一个层)
查看完整描述

1 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

刚找到在 js 中使用 .net 字节或浮点数组的方法。


C#:

[Inject] //Injected JSRuntime from Blazor DI

private IJSRuntime JSRuntime { get; set; }


byte[] bytes1;

float[] floats2;

...

if (JSRuntime is IJSUnmarshalledRuntime webAssemblyJSRuntime)

{

    webAssemblyJSRuntime.InvokeUnmarshalled<byte[], float[], object> 

        ("downloadArray", bytes1, floats2);

}

脚本:

function downloadArray(bytes1, floats2) {

    // Easy way to convert Uint8 arrays

    var byteArray = Blazor.platform.toUint8Array(bytes1);


    // Adapted method above for float32

    var m = floats2 + 12;

    var r = Module.HEAP32[m >> 2]

    var j = new Float32Array(Module.HEAPF32.buffer, m + 4, r);

}

这里的结果是在合理的时间段内分别来自 byte[] 和 float[] 的 Uint8Array 和 Float32Array 对象。


可能有任何获取 js 数组的方法,因为您可以从 ArrayBuffers 访问整个 .net 堆,例如 Module.HEAPU8(Uint8Array 内的堆)或 Module.HEAPF32(Float32Array 内的堆),并且可以通过 InvokeUnmarshalled 参数的指针轻松访问对象.


查看完整回答
反对 回复 2023-03-03
  • 1 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信