You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
There is a significant performance gap between MONAI and SimpleITK when loading NIfTI (.nii.gz) files.
In my own benchmark I have found:
MONAI average load time: 2.0321 seconds
SimpleITK average load time: 0.1135 seconds
Using cProfile I notice that for monai, the bulk of the loading time is consumed by numpy.asanyarray. Results are the following when running a loop with monai.transforms.LoadImage 10 times:
MONAI Profiling Results
ncalls
tottime
percall
cumtime
percall
filename:lineno(function)
10
0.000
0.000
20.231
2.023
benchmark.py:11(load_with_monai)
10
0.016
0.002
20.212
2.021
monai/transforms/io/array.py:229(call)
10
0.000
0.000
19.959
1.996
monai/data/image_reader.py:927(get_data)
10
0.000
0.000
19.956
1.996
monai/data/image_reader.py:1018(_get_array_data)
60/40
17.903
0.298
19.956
0.499
{built-in method numpy.asanyarray}
10
0.000
0.000
2.053
0.205
nibabel/arrayproxy.py:436(array)
10
0.000
0.000
2.053
0.205
nibabel/arrayproxy.py:413(_get_scaled)
10
0.000
0.000
2.052
0.205
nibabel/arrayproxy.py:389(_get_unscaled)
10
0.041
0.004
2.050
0.205
nibabel/volumeutils.py:392(array_from_file)
10
0.052
0.005
2.008
0.201
{method 'readinto' of '_io._BufferedIOBase' objects}
Note: Times are in seconds. 'ncalls' is the number of calls, 'tottime' is the total time spent in the function (excluding time in subfunctions), 'percall' is the average time spent per call, and 'cumtime' is the cumulative time spent in the function and all subfunctions.
As shown in the profiling results, the majority of time in MONAI is spent in numpy operations, particularly numpy.asanyarray, which takes about 19.956 seconds cumulatively. In contrast, SimpleITK's ReadImage function takes only 1.076 seconds.
import time
import os
import numpy as np
import monai
import SimpleITK as sitk
import cProfile
Custom LoadImage with prefetching
class FastMONAILoadImage(monai.transforms.LoadImage):
def call(self, filename):
data = super().call(filename)
# Directly extract the image array to bypass unnecessary numpy operations
return np.asarray(data[0]) # Only return the image array
# Profile the MONAI loading process
cProfile.runctx('load_with_monai(file_path)', globals(), locals(), filename="monai_profile.prof")
for _ in range(num_iterations):
_, monai_time = load_with_monai(file_path)
monai_times.append(monai_time)
_, sitk_time = load_with_sitk(file_path)
sitk_times.append(sitk_time)
print(f"MONAI average load time: {np.mean(monai_times):.4f} seconds")
print(f"SimpleITK average load time: {np.mean(sitk_times):.4f} seconds")
if name == "main":
file_path = "path/to/file.nii.gz"
if not os.path.exists(file_path):
print(f"File not found: {file_path}")
else:
run_benchmark(file_path)
Describe the bug
There is a significant performance gap between MONAI and SimpleITK when loading NIfTI (.nii.gz) files.
In my own benchmark I have found:
Using cProfile I notice that for monai, the bulk of the loading time is consumed by
numpy.asanyarray
. Results are the following when running a loop with monai.transforms.LoadImage 10 times:MONAI Profiling Results
SimpleITK Profiling Results
Note: Times are in seconds. 'ncalls' is the number of calls, 'tottime' is the total time spent in the function (excluding time in subfunctions), 'percall' is the average time spent per call, and 'cumtime' is the cumulative time spent in the function and all subfunctions.
As shown in the profiling results, the majority of time in MONAI is spent in numpy operations, particularly numpy.asanyarray, which takes about 19.956 seconds cumulatively. In contrast, SimpleITK's ReadImage function takes only 1.076 seconds.
To Reproduce
Environment
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: