J'ai deux float32Arrays chacun d'eux d'une longueur de 1,6 * 10 ^ 7 (réseau à point flottant). Utilisation de JS i Récupérez-les du serveur et ajoutez-les d'élément par élément. Ma page Web cesse de répondre et je reçois le message d'erreur suivant. Existe-t-il un moyen de gérer d'énormes tableaux sur le côté du client sans utiliser JS ou avec JS?
Je n'ai pas previle à commenter. Donc, je l'ajoute comme une réponse ici.
Mon navigateur (Firefox 47) a été capable de définir des valeurs pour 50 000 000 éléments d'un float32Array, un par un, de moins d'une seconde (ce n'est pas un insert/annexe cependant). Il a manqué de mémoire au-delà de cela.
Je suppose que votre goulot d'étranglement (AVERTISSEMENT DE NAVIER) a plus à voir avec une récupération/traitement lente des éléments, peu à la fois et de garder le fil de navigateur principal occupé.
Si vous avez vraiment besoin que de nombreuses données soient extraites/traitées/insérées, tout en laissez le navigateur rester réactif à l'utilisateur, vous pouvez envisager de considérer le multi-threading dans HTML5 (ou des bibliothèques JavaScript fournies par Mozilla et d'autres personnes). . Cela vous aidera à décharger le travail occupé dans un fil de fond.
Utilisez Demandes de gamme Pour obtenir les données du serveur Chunk par morceau et renvoyez-le au serveur chunk-by-morceau. Un exemple d'utilisation des demandes de plage, basé sur cette question SO _ question est présenté ci-dessous:
var chunkSize = 8388608; // for 8MB segments
function getPartialSegment(fileURL, chunkN, processData, whenError, prevreq){
var xmlhttp = prevreq || new XMLHttpRequest();
xmlhttp.open("GET", fileURL, true);
xmlhttp.setRequestHeader(
"Range",
"bytes=" + (chunkN*chunkSize) + "-" + ((chunkN+1)*chunkSize - 1)
);
xmlhttp.responseType = 'arraybuffer';
xmlhttp.onload = function(){
var response = xmlhttp.response;
if (response && (+xmlhttp.status === 200 || response.length > 0)){
if (response.byteLength%4){
if (!response.transfer){
var responseUint8 = new Uint8Array(response),
tmpDataBuffer=new ArrayBuffer(Math.floor(response.byteLength/4)*4+4),
tmpDataUint8 = new Uint8Array(tmpDataBuffer)
tmpDataUint8.set( responseUint8 );
processData(new Float32Array(tmpDataBuffer), xmlhttp)
} else processData(new Float32Array(ArrayBuffer.transfer(response,
Math.floor(response.byteLength/4)*4+4)),xmlhttp)
} else processData(new Float32Array(response), xmlhttp);
} else if (whenError instanceof Function)
whenError(xmlhttp.status, xmlhttp);
};
xmlhttp.send( null );
};
Toutefois, veuillez noter que pour cette méthode de fonctionnement, vous devrez configurer vos serveurs pour accepter les demandes de portée. Ensuite, Basé sur cet autre SO POST , vous pouvez obtenir la taille du fichier distant. Cependant, cela nécessitera votre serveur de définir l'en-tête content-length
sur la taille du fichier. Donc, vous mettez tout ensemble dans un petit parseur, vous obtenez quelque chose comme ceci (l'extrait de code suivant est entièrement fonctionnel, sauf qu'il nécessite le getPartialSegment
ci-dessus):
function proccessEntireFileInChunks(fileURL, processData, allDone, whenError){
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("HEAD", fileURL, true);
xmlhttp.onload = function(){
var filelen = parseInt(xmlhttp.getResponseHeader("Content-Length"))
if (xmlhttp.status === 200 || !isNaN(filelen)){
var chunks = Math.ceil(filelen / chunkSize),
chunkN = 0;
if (!chunks) return allDone && allDone();
getPartialSegment(fileURL, chunkN, function nextFile(response){
processData(response, chunkN*chunkSize, filelen, xmlhttp);
if (++chunkN !== chunks){
getPartialSegment(fileURL, chunkN, nextFile, whenError, xmlhttp);
} else return allDone && allDone();
}, whenError, xmlhttp);
} else if (whenError instanceof Function)
whenError(xmlhttp.status, xmlhttp);
};
xmlhttp.send( null );
}
Cela dit tout cela, je dois juste dire que si vous allez ajouter uniquement les éléments, il taxera le serveur beaucoup moins pour les ajouter sur le serveur au lieu du client. Moi aussi je suis très enthousiaste à propos de déplacer autant que possible le traitement au client, mais j'envoie des données sur un réseau uniquement pour l'addition, c'est beaucoup moins efficace qui l'ajoutant sans l'envoyer sans l'envoi d'un réseau. Je ne serais pas surpris si en interne, il ajoute un pointeur utilisé pour lire/écrire tous les octets dans les données sur la demande de réseau de la demande de réseau qui l'envoyant sur le réseau pour obtenir l'addition de 3 ajouts supplémentaires (minimal nud absolu, bien que probablement plus en réalité) par octet dans votre matrice sur le serveur qui aurait pu être juste un seul ajout par élément sur le serveur.
La réponse est celle-ci vous ne pouvez pas Processez tout ce que ces trucs thathether, parce que c'est trop.
Vous devriez repenser ce que vous faites, une solution possible sont: