Для реального использования библиотеки CRTP посмотрите на ATL и WTL (wtl.sf.net). Это используется экстенсивно там для полиморфизма времени компиляции.
Вместо того, чтобы сосредоточиться на производительности, вы можете использовать некоторые из следующих инструментов статического анализа для выявления любых ошибок / потенциальных ошибок в коде и их исправления. Иногда они помогают выявить проблемы с производительностью:
Оба они включают плагины Eclipse.
Если ваш код использует несколько критически важных структур данных, и особенно отображает / устанавливает / все, что требует большого количества поисков, вы можете убедиться, что используете их оптимально.
Например, если вы используете коллекции на основе хеша, насколько хороша ваша хеш-функция с точки зрения создания равномерного распределения? Обычно это не проблема, но в некоторых случаях это может дать хорошую экономию, поскольку ваша хеш-таблица может по существу работать как связанный список.
Кроме того, помните, что вычисление хешей и равенства не является бесплатным. Проверьте, насколько эффективно вычисляется ваш хэш. Предположим, у вас есть несколько числовых полей и несколько полей String; вычисление хэша, основанного исключительно на числовых полях, может не дать такого хорошего хеширования, но может сэкономить вам затраты на хеширование целых строк. Так же, посмотрите, можете ли вы изменить порядок проверок на равенство, чтобы сделать более дешевые и с большей вероятностью провалить тесты в первую очередь, особенно если ваши проверки на равенство были сгенерированы автоматически.
Та же проблема распространяется на коллекции, основанные на сравнении (например, TreeSet), может иметь смысл посмотреть, можете ли вы оптимизировать свою функцию сравнения. Например, можете ли вы сначала провести более дешевые сравнения? (при условии, что вы используете сравнение только для функций).
Use a profiler and let it tell you where the most frequently used and where most time is spent. Then you know for sure what needs attention and one can iteratively improve the targetted areas of the system.
Хотя обычно рекомендуется тратить время только на оптимизацию кода, которая на самом деле является проблемой, есть несколько вещей, которые вы можете сделать само собой.
Канонический пример - в C. Рассмотрим цикл
for (int ct = 0; ct
Здесь strlen
фактически сканирует массив char
в поисках символа терминатора NUL
. Это операция O (n), что делает весь цикл O (n ^ 2). Следовательно, в C возьмите strlen
за пределы с помощью const int len = strlen (str);
. Вы могли бы сделать то же самое в Java (я делаю), но это оказывает незначительное влияние на производительность. Код по вкусу.
Возвращаясь к вещам, которые действительно применимы к Java:
ArrayList
вместо LinkedList
. Вы можете найти подробности здесь и в другом месте, но LinkedList
имеет тенденцию быть медленным, даже если вы думаете, что он будет быстрым. Возможно, хорошее место для начала - это попытаться увидеть, где ваше приложение может нарушить или нарушить любые SLA. Если нет никаких конкретных жалоб на производительность, попробуйте повысить требования к производительности и посмотрите, какие части кода вызывают проблемы.
Если у вас есть функции, чувствительные ко времени, попробуйте протестировать их при большей загрузке системы или с более жесткими ограничениями. Если у вас есть большие требования к пространству, увеличьте размер данных или ограничьте пространство кучи. Если у вас возникнут проблемы в этих сценариях, устраните эти горячие точки.
Хотя это может не повлиять на вашу обычную повседневную производительность, это обеспечит доступность вашей системы при загрузке системы или пиковом вводе.
Правила оптимизации
Как некоторые из ребят сказали ранее, вы можете использовать FindBugs для устранения наиболее очевидных "ошибок", связанных с производительностью. Вы можете быстро выявить множество проблемных фрагментов кода.
Вы можете посмотреть список на сайте FindBugs http://findbugs.sourceforge.net/bugDescriptions.html .
Все улучшения производительности будут улучшены алгоритмами.
Я согласен с другими, которые только оптимизируют код ПОКАЗАНО медленным (профилировщиком, с Java 6 и 10 и более поздними версиями jvisualvm очень легко начать использовать).
Если вам нужно что-то сделать, вот некоторые вещи, которые, я уверен, не выполнены:
Любой из этих пунктов улучшит базу кода без фактического изменения кода без надобности.
По сути, это ТАКЖЕ документация, поскольку она четко демонстрирует, как использовать библиотеку и какие граничные случаи можно ожидать.Любой из этих пунктов улучшит базу кода без фактического изменения кода без надобности.
По сути, это ТАКЖЕ документация, поскольку она четко демонстрирует, как использовать библиотеку и какие граничные случаи можно ожидать.Любой из этих пунктов улучшит базу кода без фактического изменения кода без надобности.
Что касается производительности, сначала убедитесь, что у вас есть реальная проблема, а если да, то используйте профилировщик, такой как TPTP или JMeter [редактировать: HPJMeter когда-то был общим инструментом производительности Java, но теперь он Специфично для HP / UX]. Интуиция - очень плохой проводник.
Не забудьте описать реалистичный сценарий испытания. Затем сконцентрируйте свое внимание на методах, которые отображаются в верхней части статистики. Вспеньте, промойте и повторите. Также заранее решите, когда остановиться: когда производительность удовлетворительна, вы не хотите тратить время на микрооптимизации, которые делают ваш код более непонятным.
Ищите также алгоритмические оптимизации, а не только низкоуровневые настройки кодирования Java. Они могут иметь огромное влияние.
Обязательно прочтите Настройка производительности Java , чтобы узнать о стратегиях и идеях.
Имейте в виду, что по мере нагрева вашего приложения оно будет работать быстрее (например, ему больше не нужно выполнять загрузку классов, однократную инициализацию, JIT-компиляцию).
Однажды я потратил несколько месяцев на утроение производительности браузера VoiceXML на основе Java, чтобы снизить затраты на оборудование на сайтах, использующих его. Я снова и снова удивлялся тому, где находились горячие точки. Итак, как рекомендует @DarkSquid, не угадайте, измерьте.
Мне кажется, вы ищете антипаттерны производительности. Это хорошо и все такое, но если вы не поместите их в контекст своего приложения, все будет просто кодить .
Я избавился от прямого вызова этого метода на 3 секунды. Меня не волнует, что он выполняется только один раз в пакетном задании каждые 12 лет.
Если вы действительно заботитесь о производительности и о том, что воспринимают ваши пользователи, независимо от того, являются ли они прямыми пользователями, операционной группой или золотыми донорами, это это то, на что вам следует обратить внимание при повышении производительности:
Пожалуйста, просто Google "Профилировщик Java" .
Не просто просматривайте код и меняйте что-то. Как говорят другие, не устраняйте проблемы с производительностью, пока не докажете, где они.
Я использую этот простой метод.
С 7000+ классами я бы поставил большие деньги на то, что ваша система слишком продумана и что у вас проблемы с производительностью типа слишком многих уровней абстракции.
Происходит то, что простые вызовы функций и методов выглядят невинно, а код обработки событий считается "передовым фронтом", но если вы запустите его и подождите, пока он не станет медленным, затем "приостановите" несколько раз, вы увидите что-то вроде этого:
иногда для 20-30 уровней глубокий.
Любой из этих слоев, которые появляются в нескольких выборках, если бы их можно было избежать, сэкономил бы большой процент времени выполнения.
Во-первых, попытайтесь повысить производительность только в тех местах, которые, как вы знаете, сильно ограничивают производительность. На самом деле это можно определить только с помощью профилировщика. Есть несколько хороших инструментов , которые могут помочь в этом отношении.
Во-вторых, простая замена Strings на StringBuilders не приводит к повышению производительности. Фактически, во многих случаях это могло вызвать замедление. Вы должны использовать конструкторы строк только тогда, когда вы строите большую строку как часть цикла - и даже в этом случае только как часть большего рабочего цикла. Во всех остальных случаях простая конкатенация обычно выполняется быстрее.
Я бы изменил
String a = new String ("");
на
String a = "";
Найдите все места, где вы воссоздаете объект и выясните, есть ли способ просто вернуть то же значение.
Прочтите специальные главы по Эффективной версии Java 2.
Вместо того, чтобы сосредотачиваться на «медленных» частях приложения, вам следует попытаться сосредоточиться на «плохих» частях приложения.
Существует автоматизированный инструмент, который поможет вам найти ], где ваш код ведет себя как CRAP
CRAP - это действительно сокращение от инструмента! Он делает некоторые полезные вещи, такие как проверка цикломатической сложности, но действительно дает вам 10 футов взглянуть на код
Также хороший профилировщик java может помочь вам найти узкие места, если они действительно есть.
I'd say to look for the areas where the performance of the system is slow. I'm inherently a bit suspicious of attempts to naively improve performance for no sake other than for improving performance. I'd say you'd be far better off looking for appropriate locations in the code to refactor (which it sounds like some of yours already were; I'm not trying to be pedantic, though; refactoring is a very good thing, but it is NOT and should not be confused with performance improvements; refactoring can provide the opportunity for introducing performance improvement, but they're different things).
"Premature optimization is the root of all evil." - Donald Knuth
The Java compilers are also pretty good at sniffing for performance improvements, probably better than any single human. So while there are some obvious places you can improve, there is also a good possibility of making things harder for the compiler to optimize. It's much better to profile and identify the bottlenecks after compilation and focus on those. And then, the solution is probably going to be algorithmic rather than simply changing a class name. So in summary, look for a good profiler. :)
In general:
Look at complicated sections of code and see if they can be cleaned up
Pay particular attention to loops and see if any of them can be improved for performance
Recursive calls are generally big hits in performance as well. Make sure recursion is being handled properly and make sure any bits of recursion are justified.
I suggest using a quality tool. My shop uses sonar. It helps you:
Вы можете использовать инструменты статического анализа, такие как FindBugs. Компилятор javac уже пытается кое-что оптимизировать. Такие вещи, как конкатенация строк, уже оптимизированы компилятором и преобразованы в конструктор строк.
Если есть сомнения, ничто не сравнится с профилировщиком, но остерегайтесь преждевременной оптимизации.
Такие вещи, как конкатенация строк, уже оптимизированы компилятором и преобразованы в конструктор строк.Если есть сомнения, ничто не сравнится с профилировщиком, но остерегайтесь преждевременной оптимизации.
Такие вещи, как конкатенация строк, уже оптимизированы компилятором и преобразованы в конструктор строк.Если есть сомнения, ничто не сравнится с профилировщиком, но остерегайтесь преждевременной оптимизации.
Похвальная цель, но вам нужно сосредоточиться на реальных очевидных проблемах с производительностью, а не на том, где, как вы «думаете», есть проблемы с производительностью.
Проведите время в профилировщике, чтобы найти настоящие проблемы ... затем переходите оттуда. В противном случае вы просто перемешиваете код, не зная, оказываете ли вы ощутимое влияние.
Даже если бы у вас был список " To address the downvote(s) and sentiment about "I know using a PreparedStatement is faster" -- rather than asking for silver bullets, a better question to ask when faced with this issue is "how should I most productively spend my free time to make things better?" The OP clearly wants to improve the situation -- which is great...but without measuring "where it hurts" he's literally shooting in the dark. Is a PreparedStatement faster? Sure -- but if the real performance gremlin is in some other spot, why spend time 'fixing' the DB code when you could make a REAL impact by going after the actual points-of-pain?
One other thing: in a stable system such as the OP is describing, making code changes without good quantifiable justification is often considered bad practice, due to the risks introduced. In such stable systems, the question of risk/reward is for ANY code change must be considered. The risk is significant: many "simple, couldn't break anything" changes have slipped release schedules/introduced major problems. The reward? Uncertain, since you don't actually know if your change was responsible for a performance gain. Hence, we profile to make sure we're improving code which matters.
In general, just looking at the code base and attempting to improve performance by looking for certain things, does not guarantee that you'll get measurable performance gains.
Usually, it's more beneficial to use a profiler to find out which sections of code are being run the most, or conversely, which are taking the most amount of time to run, and then looking at ways to optimize those areas. This will yield the greatest benefit.
If there are performance problems, then @DarkSquid's and @AlbertoPL's advice is right on. If not, though, perhaps your time would be better spent preparing the code for future modifications. Like analyzing test coverage, particularly unit-test coverage, like assessing cyclomatic complexity or simply looking at the classes with most reported bugs (or biggest classes, or some other simple metrics). Proactive analyses like these can make the maintenance easier when that time comes.
Don't change blindly things just because they "look" like feasible.
Think about this:
logger.debug("Initializing object state " + object.initialize() );
If you simply and blindly remove that statement the object won't get initialized.
Of course such statement is wrong in first place, but, believe me they exist!!!! And will make your life miserable if something like that happens to you.
Better is to use a profiler, and find out which objects/methods/calls are consuming more time/memory/ etc. and try to identify bottlenecks.
If you have > 7k classes it is highly probable you are just fixing a bunch of code that is not being used at all.
PROFILE!!!!
Сначала я бы посмотрел, сможет ли более новое / более быстрое оборудование решить ваши проблемы. Как бы ни хотелось оптимизировать код, зачастую более экономично переместить программное обеспечение на более быстрый сервер. Мне нравится использовать инструмент тестирования производительности DaCapo для сравнения производительности Java на оборудовании. Я также веду текущий список оборудования, которое я тестировал .
Вы можете посмотреть на такие инструменты, как FindBugs, но они не исправят ваш код. Я предлагаю вам попробовать IntelliJ Community Edition, которая бесплатна. Это позволит выявить возможные проблемы с производительностью, а также быстро их исправить.
Однако лучший подход - использовать профилировщик производительности. Профилируйте реалистичный образец вашей программы, и он часто будет указывать на простые вещи, которые вы можете сделать для повышения производительности. т. е. только самое главное, что есть в профилировщике, стоит оптимизировать, остальное недостаточно, чтобы его стоило менять.