Как правильно раскрыть подстроение V8 («нарезанная строка») из его исходной строкиJavascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Как правильно раскрыть подстроение V8 («нарезанная строка») из его исходной строки

Сообщение Anonymous »

Я потратил лучшую (или, скорее, хуже) часть сегодняшней охоты на ошибку, которая заставила двигатель Node.js случайным образом исчерпывать память при поиске гигантской линии файла журнала по линии по вспомоганию. Количество совпадений не было проблемой, но рассеяние по файлу было. Для справки, это код, который я использую для разбивания входов двоичного потока на строки линии: < /p>

Код: Выделить всё

/**
*
* @param {ReadableStreamDefaultReader} reader
* @returns {AsyncGenerator}
*/
export default async function* asyncLineIterator(reader, cancelReader = true) {
let prefetch = null;
let wasDone = false;
try {
const utf8Decoder = new TextDecoder("utf-8");
// const response = await fetch(fileURL);
// const reader = response.body.getReader();
let { value: binaryChunk, done: readerDone } = await reader.read();
let chunk = binaryChunk ? utf8Decoder.decode(binaryChunk) : "";

const newline = /\r?\n/gm;
let startIndex = 0;
let result;

prefetch = reader.read();

while (true) {
const result = newline.exec(chunk);
if (!result) {
if (readerDone) {
break;
}

const remainder = chunk.substr(startIndex);
({ value: binaryChunk, done: readerDone } = await prefetch);

if (!readerDone) {
prefetch = reader.read();
chunk = remainder + (binaryChunk ? utf8Decoder.decode(binaryChunk, {stream: true}) : "");
}
else {
prefetch = null;
chunk = remainder;
}

startIndex = newline.lastIndex = 0;
continue;
}
yield chunk.substring(startIndex, result.index);
startIndex = newline.lastIndex;
if(chunk.length > 10*1024*1024) {
throw new Error("Line too long, aborting.");
}
}

if (startIndex < chunk.length) {
// Last line didn't end in a newline char
yield chunk.substr(startIndex);
}
wasDone = readerDone;
}
catch (e) {
console.trace(e);
throw e;
}
finally {
if(prefetch) {
await prefetch;
}
//console.log("Done reading lines.");
if(cancelReader && !wasDone) {
await reader.cancel();
}
}
}
< /code>
Что происходило в моем коде и вызвало сбою: < /p>

[*] Полученные кусочки были 66 КБ.substr
выше создает нарезанную строку и сохраняет ссылку на оригинальный кусок 66 КБ
[*]

Код: Выделить всё

RegExp.exec
также удерживает ссылку на срез срезы, сохранив 66 -килограммовый кусок
[*] В особом случае было умеренное количество совпадений, далеко друг от друга
Снимок перед сбоем:

Это один из моих матчей, содержит строки 66 тыс. Несмотря на то, что это как 60 -м. На данный момент следующее: < /p>

Код: Выделить всё

        /**
* @template TInput
* @param {TInput} str
* @returns {TInput}
*/
function unrefLine(str) {
return JSON.parse(JSON.stringify(str));
}
< /code>
, который я звоню с массивом соответствия: < /p>
const match = myRegex.exec(lineStr);
if(match) {
myMatches.push({matches: unrefLine([...match]), matchedLine: unrefLine(lineStr)});
}
< /code>
Это решило все сбои. Мой вопрос здесь: если есть более быстрый и менее уродливый, чем json.stringify 
. Цель состоит в том, чтобы заставить v8 забыть, что подстроение принадлежит исходной части из файла, который я читаю.

Подробнее здесь: https://stackoverflow.com/questions/794 ... rce-string
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Javascript»