massive regression in seek times
bjarthur opened this issue · 3 comments
prior to 18feda2 and with av=8 the time to index into AVI files was independent of the frame number:
>>> import timeit
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = vid[i]', number=10, setup='import pims; vid=pims.open("my.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
/groups/scicompsoft/home/arthurb/projects/turaga/stern/src/pims/pims/pyav_reader.py:229: MethodDeprecationWarning: VideoStream.seek is deprecated.
self._stream.seek(timestamp + self._first_pts)
deprecated pixel format used, make sure you did set range correctly
(repeated 999 more times)
1.546589694917202
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = vid[500+i]', number=10, setup='import pims; vid=pims.open("my.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 1000 more times)
1.5658197700977325
but with av=9 and the above commit (necessary for av=9 to work), seeking to a large frame number takes much longer that accessing a frame near the beginning of the video:
>>> import timeit
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = vid[i]', number=10, setup='import pims; vid=pims.open("my.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 1008 more times)
1.4947664067149162
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = vid[500+i]', number=10, setup='import pims; vid=pims.open("my.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 6000 more times)
5.511513814330101
is there anyway to fix this? a workaround? i suspect it is av/ffmpeg's fault. but the latest release of pims is now unusable for my purposes because of this degredation in performance. :(
The number of times that the warning comes out is interesting. This makes me think that there is some sort of line-painter bug going on where as you pull frames one-at-a-time it goes back to the start and scans all the way forward.
I took a quick look at the code and there is a bunch of caching logic but did not work out exactly how it worked. My guess is that there may be a way to keep better track of where we are in pims and not trigger the full "scan from the beginning" logic.
I also wonder if you do vid[500:600]
if you will get better performance?
I also wonder if using something like islice
here would give better performance?
I am on pims==0.6.1
and av=10.0.0
and I am experiencing huge delays when building the index via video = pims.PyAVReaderIndexed(video_file)
.
I wondered whether this is related to the issue here and if downgrading to av 8 (or even before?) is the only solution (I have not tried downgrading yet)?
thanks for the suggestions @tacaswell. unfortunately, vid[500:600]
is just as slow, and islice
even slower:
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = vid[i]', number=10, setup='from itertools import islice; import pims; vid=pims.open("/Volumes/arthurb/projects/turaga/stern/20220203_121152_10A_NA.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 1008 more times)
1.3438723559956998
>>> timeit.timeit('slices[:,:,:,:] = vid[500:600]', number=10, setup='import pims; vid=pims.open("/Volumes/arthurb/projects/turaga/stern/20220203_121152_10A_NA.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 6000 more times)
4.603510279994225
>>> timeit.timeit('for i in range(100): slices[i,:,:,:] = list(islice(vid,i,i+1))[0]', number=10, setup='from itertools import islice; import pims; vid=pims.open("/Volumes/arthurb/projects/turaga/stern/20220203_121152_10A_NA.avi"); import numpy as np; slices=np.zeros((100,380,380,3),dtype=np.float32)')
deprecated pixel format used, make sure you did set range correctly
deprecated pixel format used, make sure you did set range correctly
(repeated 49987 more times)
49.9950048019964