У меня есть Emscripten C ++ Web Worker, какой дизайн более эффективен для передачи больших данных в программу JavaScript?
Так как веб-работник делает clone()
и сериализация, для передачи через систему сообщений веб-работника, здесь есть некоторые издержки. Также необходим некоторый код для перевода полученных данных на стороне C ++ из HEAP32 в массивы JavaScript ( C -> JS
).
Под эффективностью я подразумеваю, какой дизайн быстрее, т. Е. Какой дизайн приводит к меньшему запуску new
а также gc()
(конструирование и разрушение объектов JS). Мой Web Worker использует основную функцию, написанную на C ++, которая возвращает большие массивы (два массива float[V][3]
а также int[N][3]
с N = V = 10000. Он будет использоваться для обновления геометрии ThreeJS и будет вызываться десятки тысяч раз в течение длительного периода времени на веб-странице. Помимо того, что это медленно, это также может вызвать замедление работы браузера, зависание или сбой.
C++ -> JS -> message(serialise) -> JS
, Дизайн: (C++)JS <-WW-> JS
, файлы: core_mc_algorithm.cpp, worker.js, main.js.-s BUILD_AS_WORKER=1
напишите другой код C ++ на главной стороне, которая получила данные, и преобразуйте результаты из HEAP в JS на главной стороне: (средство отслеживания данных WebWorker, обработанное Emscripten): Pros: эффективный перевод, но требуется два преобразования. риск: на стороне C ++ требуется многократное копирование из вектора в массив и т. д. Обмен данными: C++ -> message(serialise) -> C++ -> JS
, Дизайн: (C++) <-WW-> C++(JS)
, файлы: worker.cpp, main.cpp, main.js.C++ -> message(serialise) -> JS
, Дизайн: (C++) <-WW-> JS
, файлы: worker.cpp, main.js.У меня есть этот код на C ++, я хочу запустить его в качестве веб-работника:
void produce_object (
REAL* verts_output, int number_of_vertices,
int* faces_output, int number_of_triangles ) {
// Run Marching cubes, which produces a vector<int> and a vector<float>.
// fills in the arrays verts_output[] with coordinates (size: 3*number_of_vertices),
// fill in faces_output[] with triangle vertex indices (size: 3*number_of_triangles ), using some numerical code which includes the Marching Cubes algorithm.
}
Мне нужна следующая функция обратного вызова JavaScript для вызова с правильными параметрами. Это определено в файле HTML:
function update_mesh_geometry_callback (verts, faces) {
/* verts and faces are of type Float32Array and Int32Array of size (3*N) and (3*V). In this function they are used to create the following object, which is added to the scene.*/
var geo = new THREE.Geometry(verts, faces); // a subclass
scene.add(new THREE.Mesh(gro, mat, etc));
}
Типичный размер как минимум: number_of_vertices == 90000 = N, number_of_triangles == 8000 = V.
Я считаю, что вы после передачи. У работника есть дополнительный параметр в postMessage
метод:
https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
Переводимые работают только с ArrayBuffer
s, они также сбрасывают буфер из потока сообщений, вы должны помнить об этом, но для вашего случая это выглядит как идеальное решение, так как это позволит избежать полного копирования.
вот пример кода игрушки для того, что вы бы имели в своем работнике
var vertices = new Float32Array(100000);
var faceIndices = new Uint32Array(50000);
postMessage({vertices: vertices, faceIndices: faceIndices}, [vertices.buffer, faceIndices.buffer]);
Вы можете прочитать больше о переводе здесь:
Использование переносимых объектов из Web Worker
Других решений пока нет …