Skip to content

Optimize Dart Builder.writeListFloat32() for Float32List #8916

@bjornm

Description

@bjornm

The Dart flat_buffer Builder is slow when writing large Float32Lists because it iterates the elements one by one instead of copying the underlying memory buffer. The method can be optimized to special case when the given list is Float32List and then use faster memory copy operations. This aligns with the intentions of using typed data for cpu efficient code. Suggested code to change from:

  int writeListFloat32(List<double> values) {
    assert(!_inVTable);
    _prepare(_sizeofFloat32, 1 + values.length);
    final result = _tail;
    var tail = _tail;
    _setUint32AtTail(tail, values.length);
    tail -= _sizeofUint32;
    for (final value in values) {
      _setFloat32AtTail(tail, value);
      tail -= _sizeofFloat32;
    }
    return result;
  } 

to:

  int writeListFloat32(List<double> values) {
    assert(!_inVTable);
    _prepare(_sizeofFloat32, 1 + values.length);
    final result = _tail;
    var tail = _tail;
    _setUint32AtTail(tail, values.length);
    tail -= _sizeofUint32;

    if (values is Float32List && Endian.host == Endian.little) {
      // Fast copying of Float32List
      // Get the underlying bytes from Float32List (zero-copy view)
      final floatBytes = values.buffer.asUint8List(values.offsetInBytes, values.lengthInBytes);

      // Get the target location in our buffer
      final targetOffset = _buf.lengthInBytes - tail;

      // Bulk copy the float bytes directly to the buffer
      final targetBytes = _buf.buffer.asUint8List(_buf.offsetInBytes);
      targetBytes.setRange(targetOffset, targetOffset + floatBytes.length, floatBytes);

      tail -= floatBytes.length;
    } else {
      // non-Float32List, iterate one element at a time
      for (final value in values) {
        _setFloat32AtTail(tail, value);
        tail -= _sizeofFloat32;
      }
    }

    return result;
  } 

If this makes sense I'd be happy to share a PR. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    dartpr-requestedA Pull Request is requested to move the issue forward.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions