Мне интересно узнать о производительности / сложности построения объектов BigInteger с помощью конструктора new BigInteger(String)
.
Рассмотрим следующий метод:
public static void testBigIntegerConstruction()
{
for (int exp = 1; exp < 10; exp++)
{
StringBuffer bigNumber = new StringBuffer((int) Math.pow(10.0, exp));
for (int i = 0; i < Math.pow(10.0, exp - 1); i++)
{
bigNumber.append("1234567890");
}
String val = bigNumber.toString();
long time = System.currentTimeMillis();
BigInteger bigOne = new BigInteger(val);
System.out.println("time for constructing a 10^" + exp
+ " digits BigInteger : " + ((System.currentTimeMillis() - time))
+ " ms");
}
}
Этот метод создает BigInteger
объекты строк с цифрами 10^x
, где x=1
в начале и увеличивается с каждой итерацией. Он измеряет и выводит время, необходимое для построения соответствующего объекта BigInteger
.
На моей машине (Intel Core i5 660, JDK 6 Update 25 32 бит) вывод:
time for constructing a 10^1 digits BigInteger : 0 ms
time for constructing a 10^2 digits BigInteger : 0 ms
time for constructing a 10^3 digits BigInteger : 0 ms
time for constructing a 10^4 digits BigInteger : 16 ms
time for constructing a 10^5 digits BigInteger : 656 ms
time for constructing a 10^6 digits BigInteger : 59936 ms
time for constructing a 10^7 digits BigInteger : 6227975 ms
При игнорировании строк до 10 ^ 5 (из-за возможных искажений, вызванных эффектами кеширования процессора, JIT-компиляцией и т.д.), мы можем четко видеть сложность O (n ^ 2) здесь.
Помня о том, что каждая операция на BigInteger
создает новую из-за неизменности, , это большая эффективность для огромных чисел.
Вопросы:
-
Я что-то пропустил?
-
Почему это так?
-
Является ли это исправлено в более поздних JDK?
-
Есть ли альтернативы?
UPDATE:
Я сделал дальнейшие измерения, и я могу подтвердить утверждение из некоторых ответов: "Кажется, что BigInteger
оптимизирован для последующих числовых операций с расходом более высоких затрат на строительство для огромных чисел, которые кажутся мне разумными.