Skip to content

VST3: State performance issue #478

@sevenc-nanashi

Description

@sevenc-nanashi

My plugin has ~50MiB of state.
It looks like DPF reallocates the buffer for every 512 bytes, and this causes significant performance issue (It might be $O(N^2)$ ):

Simulation Source
def simulate(source_length)
  buffer_length = 512
  read = 0

  allocated = 0
  copied = 0

  while read < source_length
    read += buffer_length # read from source
    allocated += 1 # realloc is called
    copied += read # memory is copied by realloc
  end

  puts "== Source length: #{source_length} bytes"
  puts "Allocated: #{allocated} times"
  puts "Copied: #{copied} bytes (#{(copied / source_length.to_f * 100).round(2)}%)"
  puts "Unused buffer: #{read - source_length} bytes"
  puts
end

simulate(1 * 1024) # 1KiB
simulate(10 * 1024) # 10KiB
simulate(50 * 1024 * 1024) # 50MiB
== Source length: 1024 bytes
Allocated: 2 times
Copied: 1536 bytes (150.0%)
Unused buffer: 0 bytes

== Source length: 10240 bytes
Allocated: 20 times
Copied: 107520 bytes (1050.0%)
Unused buffer: 0 bytes

== Source length: 52428800 bytes
Allocated: 102400 times
Copied: 2684380774400 bytes (5120050.0%)
Unused buffer: 0 bytes

Looks like there's room for improvement.

Example: doubling the buffer size for every 2 allocations if there are more than 512*8 bytes:

Details
def simulate(source_length)
  buffer_length = 512
  read = 0

  allocated = 0
  copied = 0

  extended = 0
  while read < source_length
    if allocated >= 8 && allocated % 2 == 0
      extended += 1
      buffer_length *= 2
    end
    read += buffer_length # read from source
    allocated += 1 # realloc is called
    copied += read # memory is copied by realloc
  end

  puts "== Source length: #{source_length} bytes"
  puts "Allocated: #{allocated} times"
  puts "Extended: #{extended} times (final buffer length: #{buffer_length} bytes)"
  puts "Copied: #{copied} bytes (#{(copied / source_length.to_f * 100).round(2)}%)"
  puts "Unused buffer: #{read - source_length} bytes"
  puts
end

simulate(1 * 1024) # 1KiB
simulate(10 * 1024) # 10KiB
simulate(50 * 1024 * 1024) # 50MiB
== Source length: 1024 bytes
Allocated: 2 times
Extended: 0 times (final buffer length: 512 bytes)
Copied: 1536 bytes (150.0%)
Unused buffer: 0 bytes

== Source length: 10240 bytes
Allocated: 12 times
Extended: 2 times (final buffer length: 2048 bytes)
Copied: 48128 bytes (470.0%)
Unused buffer: 0 bytes

== Source length: 52428800 bytes
Allocated: 38 times
Extended: 15 times (final buffer length: 16777216 bytes)
Copied: 234953728 bytes (448.14%)
Unused buffer: 14682112 bytes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions