beacon-biosignals / Onda.jl

A Julia package for high-throughput manipulation of structured signal data across arbitrary domain-specific encodings, file formats and storage layers
Other
68 stars 5 forks source link

add `Base.copy` implementation #131

Closed ericphanson closed 2 years ago

ericphanson commented 2 years ago

I have seen a proliferation of deepcopy on Samples objects in Beacon-internal projects, and generally when I see deepcopy I think there's a missing copy method.

The internal use cases I have seen generally have the requirement that the data is copied, as well as the channels vector in the info object. E.g. you may want to copy, then perform an in-place montaging that updates the channels vector, and want the original unaffected.

That motivated the implementation here, where we shallow-copy each field of the SamplesInfo.

If we don't like this approach we could decide deepcopy is indeed the right approach for this. I benchmarked after implementing, and here deepcopy isn't that bad for performance (probably because it's mostly a big chunk of contiguous data, which Julia's serializer is optimized for):

julia> info = SamplesInfo(kind="eeg",channels=string.(1:19), sample_unit="unit",
                              sample_resolution_in_unit=1.0,
                              sample_offset_in_unit=0.0,
                              sample_type=Int16,
                              sample_rate=100.0)
Row(Schema("onda.samples-info@1"), (kind = "eeg", channels = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"], sample_unit = "unit", sample_resolution_in_unit = 1.0, sample_offset_in_unit = 0.0, sample_type = "int16", sample_rate = 100.0))

julia> samples = Samples(rand(sample_type(info), 19, 153600), info, true); # ~20 minutes of EEG

julia> @btime copy($samples);
  188.167 μs (30 allocations: 5.57 MiB)

julia> @btime deepcopy($samples);
  192.917 μs (40 allocations: 5.57 MiB)

julia> samples = decode(samples);

julia> @btime copy($samples);
  273.834 μs (30 allocations: 5.57 MiB)

julia> @btime deepcopy($samples);
  279.000 μs (40 allocations: 5.57 MiB)