diff --git a/doc/changes/dev/14251.newfeature.rst b/doc/changes/dev/14251.newfeature.rst new file mode 100644 index 00000000000..db0fb37c89c --- /dev/null +++ b/doc/changes/dev/14251.newfeature.rst @@ -0,0 +1 @@ +Speed up :func:`mne.io.read_raw_persyst` and :func:`mne.io.read_raw_nihon` by decoding data in cache-sized blocks rather than materializing the whole request, by `Bruno Aristimunha`_. diff --git a/mne/io/nihon/nihon.py b/mne/io/nihon/nihon.py index 61dabd4a03f..feb2067e7a2 100644 --- a/mne/io/nihon/nihon.py +++ b/mne/io/nihon/nihon.py @@ -418,6 +418,10 @@ def _map_ch_to_specs(ch_name, chan_labels_upper): return out +# decode in cache-sized blocks rather than one huge one (1.8x on a 106 MB file) +_BLOCK_BYTES = 1024**2 + + @fill_doc class RawNihon(BaseRaw): """Raw object from a Nihon Kohden EEG file. @@ -566,13 +570,20 @@ def _read_segment_file(self, data, idx, fi, start, stop, cals, mult): rel_start = start - ends[start_block - 1] start_offset = datastart + rel_start * n_channels * 2 + # Decode a few MB at a time: each step below builds a temporary the + # size of the block, so reading the whole request at once pushes + # them all out of cache. + n_times = stop - start + n_block = max(1, _BLOCK_BYTES // 2 // n_channels) with open(self.filenames[fi], "rb") as fid: - to_read = (stop - start) * n_channels fid.seek(start_offset) - block_data = np.fromfile(fid, "