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

我有一个 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 s


C# 调用 js 和总和的时间:7.000 秒


这似乎是一个相当高的开销时间......有谁知道是否有办法加快这个速度(真正的功能做了我目前在 Blazor/C# 中不能做的事情 - 在 Leaflet 中更新一个层)


一只斗牛犬
浏览 204回答 1
1回答

斯蒂芬大帝

刚找到在 js 中使用 .net 字节或浮点数组的方法。C#:[Inject] //Injected JSRuntime from Blazor DIprivate IJSRuntime JSRuntime { get; set; }byte[] bytes1;float[] floats2;...if (JSRuntime is IJSUnmarshalledRuntime webAssemblyJSRuntime){&nbsp; &nbsp; webAssemblyJSRuntime.InvokeUnmarshalled<byte[], float[], object>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ("downloadArray", bytes1, floats2);}脚本:function downloadArray(bytes1, floats2) {&nbsp; &nbsp; // Easy way to convert Uint8 arrays&nbsp; &nbsp; var byteArray = Blazor.platform.toUint8Array(bytes1);&nbsp; &nbsp; // Adapted method above for float32&nbsp; &nbsp; var m = floats2 + 12;&nbsp; &nbsp; var r = Module.HEAP32[m >> 2]&nbsp; &nbsp; var j = new Float32Array(Module.HEAPF32.buffer, m + 4, r);}这里的结果是在合理的时间段内分别来自 byte[] 和 float[] 的 Uint8Array 和 Float32Array 对象。可能有任何获取 js 数组的方法,因为您可以从 ArrayBuffers 访问整个 .net 堆,例如 Module.HEAPU8(Uint8Array 内的堆)或 Module.HEAPF32(Float32Array 内的堆),并且可以通过 InvokeUnmarshalled 参数的指针轻松访问对象.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript