То, что вы запрашиваете, известно в академической области CS как «частично постоянные массивы». Для получения дополнительной информации о стойкости см. опрос Каплана .
Одним из простых решений является использование поисковых деревьев вместо массивов. Вы можете использовать чисто функциональные сбалансированные деревья поиска, чтобы гарантировать, что для каждого чтения или записи требуется время O (lg n) наихудшего случая (где n - размер массива) вместо времени O (1). (Если вы храните версии с метками времени в расширяемом массиве, добавление новой версии будет O (1) амортизироваться, а доступ к старой версии будет O (1) в худшем случае.)
Если вы не знакомы с чисто функциональными деревьями поиска, вы можете прочитать это введение в постоянные массивы Clojure . Они являются чисто функциональными деревьями, индексированными целыми числами фиксированной ширины (в форме дерева), и, следовательно, имеют фиксированную глубину. Это может быть самым быстрым решением вашей проблемы, как в наихудшем случае, так и в реальной жизни.
Единственные другие частично постоянные массивы, о которых я знаю, могут занять больше времени в худшем случае. У некоторых сложность лучше амортизируется, а у некоторых ожидаемая сложность выше, если доступ к массивам осуществляется различными ограниченными способами.