Проблема с BigInteger заключается в том, что он неизменен: другими словами, если у вас есть объект BigInteger, вы не можете изменить значение самого объекта, вы можете заменить его только новым объектом.
Теперь это обычно хорошо, так как предотвращает алиасы и т. Д. (Вы не хотите, чтобы ваши «2 + 3» где-то внезапно превращались в «2 + 5», потому что пользователь этого «3» где-то еще в вашей программе поменял его на "5"). Однако внутри BigInteger использует массив для хранения компонентов этого значения. Для большого числа этот массив может быть довольно большим; BigInteger, представляющий базиллион, может нуждаться в массиве, скажем, тысячи элементов.
Так что же происходит, когда я хочу добавить один к этому BigInteger? Итак, мы создаем новый BigInteger, который, в свою очередь, создаст новый массив, состоящий из тысячи элементов, скопирует все элементы внутреннего массива старого BigInteger во внутренний массив нового BigInteger, за исключением последнего, и вставит новая версия этого последнего элемента увеличивается на единицу. (Или может потребоваться обновить последние два.) Если вам тогда не нужно старое значение, оно освобождает тот старый BigInteger, который освобождает массив.
Это, очевидно, довольно неэффективно, если вы все равно избавляетесь от старых значений. Поэтому, если у вас есть подобные операции, вы можете вместо этого использовать MutableBigInteger, который можно увеличить, просто изменив последний элемент во внутреннем массиве существующего MutableBigInteger. Это намного быстрее! Тем не менее, это разрушает старую ценность, которая может быть проблематичной, как я указал выше. Если кто-то даст вам int 3, вы можете ожидать, что он останется прежним. Если кто-то дает вам MutableBigInteger, не ожидайте, что это будет тот же самый номер позже!