Шаблон "прототипа" Java-новый vs clone vs class.метод newinstance
в моем проекте есть некоторые фабрики "прототипов", которые создают экземпляры путем клонирования конечного частного экземпляра.
автор этих фабрик говорит, что этот шаблон обеспечивает лучшую производительность, чем вызов "нового" оператора.
используя google, чтобы получить некоторые подсказки об этом, я не нашел ничего важного. Вот небольшой отрывок, найденный в A javdoc из неизвестного проекта
к сожалению, clone() работает медленнее, чем назвав новый. Однако это много быстрее, чем вызов Ява.ленг.Класс.newInstance (), и несколько быстрее, чем катить наши собственные метод "клонирования".
для меня это выглядит как старая лучшая практика времени java 1.1. Кто-нибудь знает об этом больше ? Это хорошая практика использовать это с "современной" jvm ?
6 ответов
абсолютно, Этот тип практики полностью устарел. С тех пор виртуальная машина Java значительно улучшилась. Создание объектов крайне дешево. Другая связанная с этим практика, объединение объектов, также устарела, потому что стоимость создания и очистки объектов теперь намного эффективнее. В некоторых случаях это может быть полезно (Джон Скит дает несколько хороших примеров тут), но никоим образом не должен быть частью базовой библиотеки framework, такой как эта.
Я бы предложите найти новые библиотеки и / или новый проект для работы ;-)
проверьте этот класс статья Java Городские Легенды Производительности для более полного представления.
Gee. Это одна из худших идей, которые я когда-либо слышал.
Не делайте странных вещей. Даже если вы измерили и видите некоторое явное улучшение (ну, в этом случае нулевой шанс), подумайте, прежде чем делать это.. Кто знает, что это будет исправлено в следующем JVM. Тогда у вас остается какой-то странный кусок кода, который работает хуже, трудно читать, и некоторые ошибки из-за этого.
Я имею в виду, что люди, разрабатывающие JVM, не идиоты! Использовать new
!
Я думаю, вы должны избавиться от этой странной части кода.
как говорили другие, это устаревшая практика. Это устаревший шаблон, который, к сожалению, с новыми JVMs добавит больше раздувания в код без повышения производительности.
Я хочу код, чтобы я мог делиться, но некоторое время назад я сделал простой тест производительности этой модели по сравнению с использованием оператора 'new', и я обнаружил, что используя оператор 'new' была в худшем по крайней мере так быстро, как этот узор, и в лучшем случае быстрее и эффективнее. Могут быть некоторые edge case мой тест не охватывал, где это все еще может быть допустимым подходом, но в целом я бы сказал, Избегайте этого шаблона.
другое Примечание, хотя, я бы предложил вам не беспокоиться об этом слишком много, если он присутствует в существующей базе кода. Но также я не стал бы писать новый код, чтобы расширить этот шаблон для большего количества частей вашего проекта, если только это не повредит ясности и согласованности вашей базы кода - в этот момент Вы должны оценить, будет ли он умным в долгосрочный рефакторинг этого кода из вашего проекта. Под "умным" я имею в виду, что рефакторинг этого кода из вашего проекта сэкономит время в будущем на разработке и отладке > количество времени, необходимое для рефакторинга этого.
нет.
О, мне нужно больше символов для ответа. Поэтому позвольте мне расширить и сказать, что такая микро-оптимизация неуместна, если нет проблемы, и если есть, то вы должны быть в состоянии измерить, если это делает вещи лучше.
Я создал простой бенчмарк для класса Person
. Я использую последний OpenJDK 8:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
и получил следующие результаты:
Benchmark Mode Cnt Score Error Units
MyBenchmark.viaClone avgt 10 10.041 ± 0.059 ns/op
MyBenchmark.viaNew avgt 10 7.617 ± 0.113 ns/op
этот простой тест демонстрирует, что создание экземпляра нового объекта и установка соответствующих свойств из исходного объекта занимает на 25% меньше времени, чем его клонирование.
мои тесты с DecimalFormat (OpenJDK 8/Windows/JMH 1.19) показывают совершенно противоположное изображение:
Benchmark Mode Cnt Score Error Units
Format.everyTimeCreate avgt 10 9326.967 ± 199.511 us/op
Format.useClone avgt 10 5102.397 ± 72.993 us/op
Format.useGlobalWithTL avgt 10 4605.604 ± 59.000 us/op
похоже, не так просто ответить, что работает лучше.