Записать сырые двоичные данные в буфер - PullRequest
0 голосов
/ 21 апреля 2019

Я работаю над функцией, которая перебирает данные PCM . Я получаю куски данных различного размера, и в настоящее время я работаю с этим путем конкатенации буфера. Проблема в том, что я уверен, что такой подход снижает производительность.

Один из простейших алгоритмов состоит из разбиения 500 фрагментов по 4800 байт (= зерна) и повторения их 3 раза следующим образом:

buf = <grain1, grain1, grain1, ..., grain500, grain500, grain500>
function(){
  // ...
  let buf = Buffer.alloc(0) // returned buffer, mutated

  // nGrains is defined somewhere else in the function
  // example: nGrains = 500
  for(let i=0;i<nGrains;i++){
    // a chunk of PCM DATA 
    // example: grain.byteLength = 4800 
    const grain = Buffer.from(this._getGrain())

    // example: nRepeats = 3
    for(let j=0;j<nRepeats;j++)
      buf = Buffer.concat([buf, grain])
  }

  return buf
}

Я чувствую, что этих тяжелых операций производительности (1500 объединяющихся мутаций) можно было бы избежать, если бы существовал какой-то способ прямой записи «необработанных данных» из заданного смещения в буфер, предварительно выделенный по размеру. Я сделал следующую вспомогательную функцию, которая дала мне ОГРОМНОЕ улучшение производительности, но я чувствую, что делаю что-то не так ...

function writeRaw(buf, rawBytes, offset) => {
  for(i=0;i<rawBytes.byteLength;i++){
    buf.writeUInt8(rawBytes.readUInt8(i), offset + i)
  }

  return buf
}

Моя функция теперь выглядит так:

function(){
  // ...
  const buf = Buffer.alloc(len) // returned buffer, immutable

  for(let i=0;i<nGrains;i++){
    const grain = Buffer.from(this._getGrain())

    for(let j=0;j<nRepeats;j++)
      writeRaw(buf, grain, (i * nRepeats + j) * grainSize)
  }

  return buf
}

Мой вопрос: есть ли более чистый (или более стандартный) способ сделать это вместо перебора байтов? Buffer.write * Кажется, 1016 * работает только для строк, хотя это было бы идеально ...

1 Ответ

1 голос
/ 21 апреля 2019

Существует Buffer.copy.

const buf = Buffer.alloc(len);

for(let i = 0; i < nGrains; i++){
  const grain = Buffer.from(this._getGrain());

 for(let j=0;j<nRepeats;j++)
   grain.copy(/*to*/ buf, /*at*/ (i * nRepeats + j) * grainSize);
}

Вы также можете использовать Buffer.fill :

  const buf = Buffer.alloc(len);

  for(let i = 0; i < nGrains; i++) {
    const grain = Buffer.from(this._getGrain());
    buf.fill(grain, i * nRepeats * grainSize, (i + 1) * nRepeats * grainSize);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...