Можно определить минимальный и максимальный размер пула путем определения MinPoolSize=xyz
и/или MaxPoolSize=xyz
в строке подключения. Этой причиной проблемы могла быть другая вещь как бы то ни было.
Ваш тест может содержать ошибки. Как правило, хотя JVM может оптимизировать нормальное создание экземпляра, но не может оптимизировать для отражающего варианта использования .
Для тех, кто интересуется, сколько времени было, я добавил фазу разогрева и использовал массив для поддержки созданного объекты (более похожие на то, что может делать настоящая программа). Я запустил тестовый код в своей системе OSX, jdk7 и получил следующее:
Отражение экземпляра заняло: 5180 мс
Обычное создание экземпляра заняло: 2001 мс
Модифицированный тест:
public class Test {
static class B {
}
public static long timeDiff(long old) {
return System.nanoTime() - old;
}
public static void main(String args[]) throws Exception {
int numTrials = 10000000;
B[] bees = new B[numTrials];
Class<B> c = B.class;
for (int i = 0; i < numTrials; i++) {
bees[i] = c.newInstance();
}
for (int i = 0; i < numTrials; i++) {
bees[i] = new B();
}
long nanos;
nanos = System.nanoTime();
for (int i = 0; i < numTrials; i++) {
bees[i] = c.newInstance();
}
System.out.println("Reflecting instantiation took:" + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");
nanos = System.nanoTime();
for (int i = 0; i < numTrials; i++) {
bees[i] = new B();
}
System.out.println("Normal instaniation took: " + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");
}
}
Отражение происходит медленно по нескольким очевидным причинам:
JIT
Исключений
, заключенных в InvocationTargetException
и повторно выброшенных и т. Д. То, что что-то в 100 раз медленнее , не означает, что это слишком медленно для вас , если предположить, что отражение - это «правильный путь» для вас при разработке вашей программы. Например, Я полагаю, что IDE интенсивно используют отражение, и моя IDE в основном в порядке с точки зрения производительности.
В конце концов, накладные расходы на отражение , вероятно, станут незначительными , когда
1138961] по сравнению с , скажем, синтаксическим анализом XML или доступом к базе данных !
Еще один момент, о котором следует помнить, это то, что микротесты - это заведомо ошибочный механизм для определения того, насколько быстро что-то происходит практика . Как и Тима Бендера , JVM требуется время для "разогрева", JIT может повторно оптимизировать горячие точки кода на лету и т. Д.
накладные расходы на отражение , вероятно, станут незначительными , когда по сравнению с , скажем, синтаксическим анализом XML или доступом к базе данных !Еще один момент, о котором следует помнить, - это то, что микротесты - это заведомо ошибочный механизм определения того, насколько быстро что-то происходит на практике . Как и Тима Бендера , JVM требуется время для «разогрева», JIT может повторно оптимизировать горячие точки кода на лету и т. Д.
накладные расходы на отражение , вероятно, бледнеют до незначительности , когда по сравнению с , скажем, синтаксическим анализом XML или доступом к базе данных !Еще один момент, о котором следует помнить, - это то, что микротесты - это заведомо ошибочный механизм определения того, насколько быстро что-то происходит на практике . Как и Тима Бендера , JVM требуется время для «разогрева», JIT может повторно оптимизировать горячие точки кода на лету и т. Д.
JITted-код для создания экземпляра B невероятно легкий. По сути, ему нужно выделить достаточно памяти (которая просто увеличивает указатель, если не требуется сборщик мусора), и это все - на самом деле нет кода конструктора, который нужно вызывать; Я не знаю, пропускает ли JIT это или нет, но в любом случае здесь особо нечего делать.
Сравните это со всем, что должно делать отражение:
... и, возможно, другие вещи, которых я не знаю ' Я даже подумал об этом.
Обычно отражение не используется в контексте, критичном к производительности; если вам нужно подобное динамическое поведение, вы можете вместо этого использовать что-то вроде BCEL .
Похоже, что если вы сделаете конструктор доступным, он будет выполняться намного быстрее. Теперь она всего в 10-20 раз медленнее, чем другая версия.
Constructor<B> c = B.class.getDeclaredConstructor();
c.setAccessible(true);
for (int i = 0; i < numTrials; i++) {
c.newInstance();
}
Normal instaniation took: 47ms
Reflecting instantiation took:718ms
И если вы используете серверную виртуальную машину, она может оптимизировать ее больше, так что она всего в 3-4 раза медленнее. Это вполне типичный спектакль. Статья , связанная с Geo, хорошо читается.
Normal instaniation took: 47ms
Reflecting instantiation took:140ms
Но если вы включите скалярную замену с помощью -XX: + DoEscapeAnalysis, тогда JVM сможет оптимизировать обычное создание экземпляра (это будет 0-15 мс) но рефлексивная реализация остается прежней.