Как сказать эффективность кода Java - PullRequest
3 голосов
/ 22 мая 2011

Я только что понял, что понятия не имею, как определить, эффективен ли фрагмент кода Java с вычислительной точки зрения. Читая несколько исходных кодов, иногда я чувствую, что код, который я читаю, крайне неэффективен, иногда я чувствую обратное.

Не могли бы вы перечислить основные однострочные правила, которые необходимо соблюдать, и почему они так важны?

edit - Мой вопрос связан с реализациями Java JVM, поэтому такие вопросы, как проблемы выделения Java, управление строками, обработка исключений, синхронизация потоков и т. Д.

Заранее спасибо

p.s. не принимайте буквально "одна строка"

Ответы [ 5 ]

8 голосов
/ 22 мая 2011

Основное однострочное правило? Хорошо, вот и вы:

Избегайте ненужных вычислений.

Как ты это делаешь? Извините, нет ответа в одну строку. (

Ну, люди проводят годы в колледже, изучая алгоритмы и структуры данных в информатике по определенной причине ... возможно, они захотят когда-нибудь пройти курс обучения по алгоритмам / структурам данных.


Я не уверен, что вы имеете в виду под «с точки зрения вычислений» (кажется, это подразумевает проблемы с алгоритмом), но если вы подразумеваете трюки, более похожие на такие, как профилирование, попробуйте следующее:

  • Запустите программу, затем внезапно приостановите ее и посмотрите, где она остановилась. Сделайте это несколько раз; где оно останавливается больше всего, является узким местом, и то, как часто оно останавливается, указывает на то, насколько оно узкое.

  • Избегать упаковки / распаковки (преобразование между int и Integer и т. Д.); особенно избегайте Integer[], List<Integer> и других вещей, которые внутренне хранят массивы объектов примитивных типов

  • Вычеркнуть общий код (иногда проблема скорости, иногда читаемость)

  • Избегайте циклических операций String; используйте взамен StringBuilder / StringBuffer. (Короче говоря, избегайте создания и / или копирования данных, когда это не нужно.)

Я добавлю к этому, если на ум придут другие вещи.

7 голосов
/ 22 мая 2011

Использовать Профилирование . Посмотрите на JProfile или любые другие профилировщики.

4 голосов
/ 22 мая 2011

Я повторю ответ Мхердада в том смысле, что определенно нет «базовых однострочных правил».

Что касается ответов, которые предполагают использование инструментов профилирования, то профилирование не очень полезно, пока вы не поймете сложность алгоритмического времени и нотацию big-O. Из статьи Википедии в записи Big O:

В математике, информатике и связанные поля, нотация big-O описывает ограничивающее поведение функция, когда аргумент стремится к определенной стоимости или бесконечность, как правило, с точки зрения более простого функции. Обозначение Big O характеризует функции в соответствии с их темпы роста: разные функционирует с той же скоростью роста может быть представлен с использованием того же O нотации.

Идея нотации big-O состоит в том, что она дает вам представление о том, как размер ввода влияет на время выполнения для данного алгоритма. Например, рассмотрим следующие два метода:

void linearFoo(List<String> strings){
    for(String s:strings){
      doSomethingWithString(s);
    }
}

void quadraticFoo(List<String> strings){
    for(String s:strings){
        for(String s1:strings){
            doSomethingWithTwoStrings(s,s1);
        }
    }
}

linearFoo называется O (n), что означает, что его время линейно возрастает с размером ввода n (т. Е. strings.size()). quadraticFoo называется O (n 2 ), что означает, что время, необходимое для выполнения quadraticFoo, является функцией strings.size() в квадрате.

Как только вы почувствуете сложность алгоритмического времени ваших программ, инструменты профилирования станут полезными. Например, вы сможете сказать, что если во время профилирования вы обнаружите, что метод обычно требует 1 мс для фиксированного размера ввода, если этот метод равен O (n), удвоение размера ввода приведет к времени выполнения 2 мс (1мс = n, следовательно, 2n = 2мс). Однако, если это O (n 2 ), удвоение размера ввода будет означать, что для выполнения вашего метода потребуется около 4 мс (1 мс = n 2 , следовательно (2n) 2 = 4 мс).

3 голосов
/ 22 мая 2011

Вы можете использовать jconsole для мониторинга взаимоблокировок, утечек памяти, потоков и кучи вашего приложения.Короче говоря, вы можете увидеть производительность ваших приложений в виде графиков.

enter image description here

2 голосов
/ 22 мая 2011

Посмотрите книгу Джошуа Блоха Эффективная Java , если вам действительно нужен список правил, которым вы должны следовать в Java.В книге даются рекомендации не только по производительности, но и по правильному способу программирования на Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...