Thanks to @JeffC and @steve-ed: the problem was with Chrome tabs. I added tab re-creation every 100 iterations:
if n != 0 and n % 100 == 0:
print('group {}: IDs {}-{} processed in {} s'.format(group, n - 100, n, time.time() - start))
driver.switch_to.new_window('tab')
curr = driver.current_window_handle
for handle in driver.window_handles:
driver.switch_to.window(handle)
if handle != curr:
driver.close()
start = time.time()
And now it gives a stable result:
group 1: IDs 100-200 processed in 11.281310081481934 s
group 1: IDs 1100-1200 processed in 9.197898626327515 s
group 1: IDs 2100-2200 processed in 10.045527458190918 s
...
group 1: IDs 5100-5200 processed in 9.298804521560669 s
...
group 1: IDs 14100-14200 processed in 9.699942350387573 s