Можете ли вы / Как вы экономите процессор и память, выбирая мудро

Я понимаю, что JVM оптимизирует некоторые вещи для вас (пока не ясно, какие именно), но позвольте мне сказать, что я должен был сделать это:

while(true) {
     int var = 0;
}

будет делать:

int var;
while(true) {
     var = 0;
}

занять меньше места? Поскольку вы не объявляете новую ссылку каждый раз, вам не нужно каждый раз указывать тип.

Я понимаю, что вам действительно нужно будет только положить вар за пределами while если бы я хотел использовать его вне этого цикла (вместо возможности использовать его локально, как в первом примере). Кроме того, как насчет объектов, будет ли это отличаться от примитивных типов в этой ситуации? Я понимаю, что это небольшая ситуация, но создание такого рода вещей может привести к тому, что мое приложение будет занимать много памяти / процессоров. Я пытаюсь использовать как можно меньше операций, но я не совсем понимаю, что происходит за кулисами.

Если бы кто-то мог мне помочь, даже, может быть, связать меня с тем, где я могу узнать о сохранении процессора за счет уменьшения количества операций, это было бы очень полезно. Пожалуйста, никаких книг (если они не бесплатны!), Нет способа получить их прямо сейчас /:

2 ответа

Не. Преждевременная оптимизация - корень всего зла.

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

Как только вы написали свой код (более или менее наивно, в зависимости от вашего уровня опыта), вы пишете тесты производительности для него. Попробуйте подумать о различных способах использования кода (много раз подряд, спереди назад или наоборот, много одновременных вызовов и т. Д.) И попытайтесь охватить их в тестовых примерах. Затем сравните ваш код.

Если вы обнаружите, что некоторые тесты не очень хороши, выясните причину. Измерьте части контрольного примера, чтобы увидеть, куда идет время. Осмотрите части, где больше всего времени уходит.

Главным образом, вы найдете странные циклы, когда при повторном чтении кода вы будете думать, что "глупо было так писать. Конечно, это медленно и легко исправить. По моему опыту, большинство проблем с производительностью можно решить таким образом, и "жесткая оптимизация" вряд ли когда-либо понадобится.

В итоге вы обнаружите, что 99* процентов всех проблем с производительностью можно решить, коснувшись только 1 процента кода. Другой код никогда не вступает в игру. Вот почему вы не должны "преждевременно" оптимизировать. Вы будете тратить драгоценное время на оптимизацию кода, в котором изначально не было проблем с производительностью. И делает его менее читабельным в процессе.

Числа, конечно, составлены, но вы знаете, что я имею в виду:)

Hot Licks указывает на тот факт, что это не очень хороший ответ, поэтому позвольте мне остановиться на этом с некоторыми хорошими советами по производительности:

  1. Следите за вводом / выводом

    Большинство проблем с производительностью не в чистой Java. Вместо этого они взаимодействуют с другими системами. В частности, доступ к диску заведомо медленный. Так же и сеть. Так что минимизируйте его использование.

  2. Оптимизировать запросы SQL

    SQL-запросы добавят секунды, даже минуты ко времени выполнения вашей программы, если вы не будете остерегаться. Так что подумай об этом очень внимательно. Опять же, сравните их. Вы можете написать очень оптимизированный Java-код, но если он сначала потратит десять секунд на ожидание, пока база данных выполнит какой-то монстр SQL-запрос, он никогда не будет быстрым.

  3. Используйте правильный вид коллекций

    Большинство проблем с производительностью связаны с выполнением заданий много раз. Обычно при работе с большими наборами данных. Размещение ваших данных на карте, а не в списке может иметь огромное значение. Также существуют специализированные типы коллекций для всех видов требований к производительности. Изучите их и выбирайте с умом.

  4. Не пишите код

    Когда производительность действительно имеет значение, выдавливание последних "выпадений" из некоторого фрагмента кода само по себе становится наукой. Если вы не пишете какой-то очень экзотический код, велика вероятность, что для решения ваших проблем будет какая-то библиотека или инструментарий. Это будет использоваться многими в реальном мире. Пробовал и проверял. Не пытайтесь побить этот код. Используй это.

Мы, скромные разработчики Java, являемся конечными пользователями кода. Мы берем строительные блоки, которые предоставляет язык и его экосистема, и связываем их вместе, чтобы сформировать приложение. По большей части проблемы с производительностью вызваны тем, что мы неправильно используем предоставленные инструменты или вообще не используем никаких инструментов. Но нам действительно нужны подробности, чтобы обсуждать их. Бенчмаркинг дает вам эту специфику. И когда медленный код идентифицирован, это обычно просто вопрос изменения коллекции из списка в карту, или сортировки заранее, или отбрасывания соединения из какого-либо запроса и т. Д.

Попытка оптимизировать код, который не нужно оптимизировать, увеличивает сложность и снижает читабельность.

Однако бывают случаи, когда улучшение читабельности также сопровождается улучшением производительности.

Например,

  • если числовое значение не может быть нулевым, используйте примитив вместо оболочки. Это проясняет, что значение не может быть нулевым, но также использует меньше памяти и снижает нагрузку на ГХ.
  • используйте набор, если у вас есть коллекция, которая не может иметь дубликатов. Часто список используется, когда на самом деле набор будет более подходящим, в зависимости от выполняемых вами операций, это также может быть быстрее за счет уменьшения временной сложности.
  • рассмотрите возможность использования перечисления с одним экземпляром для синглтона (если вам вообще нужно использовать синглтоны). Это гораздо проще и быстрее, чем двойная проверка блокировки. Подсказка: старайтесь иметь только одиночные синглы без гражданства.
  • Написание более простого, хорошо структурированного кода также облегчает оптимизацию JIT. Вот где попытка превзойти JIT с помощью более сложных решений обернется огнем, потому что вы в итоге путаете JIT, и то, что вы считаете более быстрым, на самом деле медленнее. (И это еще сложнее)
  • попытайтесь уменьшить объем записи в консоль (и IO в целом) в критических разделах. Запись на консоль обходится очень дорого, как для программы, так и для бедного человека, вынужденного читать ее, поэтому стоит потратить больше времени на создание краткого вывода на консоль.
  • попробуйте использовать StringBuilder, когда у вас есть цикл элементов для добавления. Примечание. Старайтесь не использовать StringBuilder для однострочников, а просто серию append(), поскольку это может быть медленнее и труднее для чтения.

Совершенство достигается не тогда, когда нечего добавить, а когда нечего отнять. - Антуан де Сент-Экзюпери, французский писатель (1900 - 1944)

Разработчики любят решать сложные проблемы, и существует очень сильный соблазн решать проблемы, которые не нужно решать. Это очень распространенное поведение для разработчиков с опытом работы до 10 лет (в любом случае это было для меня;), после того, как примерно до этого момента вы уже решили наиболее распространенную проблему раньше, и вы начинаете выбирать лучший / минимальный набор решений, который решит проблему. проблема. Это то, чего вы хотите достичь в своей карьере, и вы сможете разрабатывать качественное программное обеспечение гораздо быстрее, чем раньше.

Если вы мечтаете решить интересную проблему, решите ее в свое время, посмотрите, в чем ее отличие, но не включайте ее в свой рабочий код, если только вы не знаете (потому что вы измерили), что она действительно имеет значение,

Однако, если вы найдете более простое и изящное решение проблемы, это стоит включить не потому, что оно может быть быстрее (хотя это может быть так), а потому, что оно должно облегчить понимание и поддержку кода, и это, как правило, гораздо более ценно. использовать свое время. Успешно используемое программное обеспечение, как правило, стоит в три раза дороже в обслуживании, чем в разработке Делайте то, что сделает жизнь бедного человека, который должен понять, почему вы сделали что-то легче (что сложнее, если вы не сделали этого по какой-либо уважительной причине), поскольку это может быть вы однажды;)

Хорошим примером того, когда вы можете сделать приложение медленнее для улучшения рассуждений, является использование неизменяемых значений и параллелизма. Неизменяемые значения обычно медленнее, чем изменяемые, иногда гораздо медленнее, однако при использовании с параллелизмом изменяемое состояние очень трудно получить с точки зрения доказуемости, и вам это нужно, потому что тестирование это хорошо, но не надежно. Используя параллелизм, у вас гораздо больше процессорного времени, поэтому немного больше затрат на использование неизменяемых объектов - очень разумный компромисс. В некоторых случаях использование неизменяемых объектов может позволить вам избежать использования блокировок и фактически повысить пропускную способность. например, CopyOnWriteArrayList, если у вас высокий коэффициент чтения для записи.

Другие вопросы по тегам