Дорого ли создавать объекты в .Net?

Java имеет пул строк, в котором Java управляет распределением памяти для объектов String. См. String Pools в Java

Когда вы проверяете (сравниваете) два объекта с помощью оператора ==, он сравнивает равенство адресов в пуле строк. Если два объекта String имеют одинаковые адреса, то он возвращает true, в противном случае false. Но если вы хотите сравнить содержимое двух объектов String, вы должны переопределить метод equals.

equals - фактически метод класса Object, но он переопределяется в класс String и дается новое определение, которое сравнивает содержимое объекта.

Example:
    stringObjectOne.equals(stringObjectTwo);

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

Давайте посмотрим:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

13
задан Chris Arnold 21 January 2010 в 08:45
поделиться

9 ответов

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

20
ответ дан 1 December 2019 в 17:34
поделиться

Почему не статический метод в самом классе?

Общественный статический пустотный аддисисторентри (вход истории истории)

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

5
ответ дан 1 December 2019 в 17:34
поделиться

Вы оба неправильные, но он не так, как вы.

5
ответ дан 1 December 2019 в 17:34
поделиться

Это дорого по сравнению с , а не созданием объектов в .NET, точно так же, как 1 - это большое число по отношению к 0. Все зависит от вашей точки зрения. Если это в цикле, который запускается 20 миллионов раз, я могу беспокоиться, в противном случае, мне все равно.

Сказав это, я хотел бы отметить, что Утилита не является хорошим именем для класса, и рефакторинг в HistoryEntry также, скорее всего, требует, чтобы вы проверили, что передаваемый параметр не является null, требованием, которого у вас не было изначально, когда все параметры являлись типами значений.

Также обычно считается, что анти-параметр имеет объекты с данными, но не имеет поведения, каким HistoryEntry, похоже, является. Постарайтесь избегать этого слишком часто.

4
ответ дан 1 December 2019 в 17:34
поделиться

Это не очень дорого создавать объекты в .NET. Фактически, создание объекта очень быстро, даже если вы создаете миллионы из них.

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

, который сказал, что никогда не разумно избегать звонков новых до , демонстрируя, что многие объекты действительно DO замедляют GC. В вашем примере они, скорее всего, не будут.

2
ответ дан 1 December 2019 в 17:34
поделиться

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

1
ответ дан 1 December 2019 в 17:34
поделиться

. Производительность против ловкости.

0
ответ дан 1 December 2019 в 17:34
поделиться

Нет. Сборщик мусора оптимизирован, чтобы быть высокоэффективным при работе с недолгими объектами.

0
ответ дан 1 December 2019 в 17:34
поделиться

Создание нового объекта очень дешево. Вам придется создать множество объектов в очень плотном цикле, чтобы заметить разницу ... но в то же время это не бесплатно . Вы также должны иметь в виду, что затраты наполовину скрыты - у вас есть некоторая предоплата при создании объекта, но это также означает, что сборщику мусора нужно сделать больше.

Так стоит ли более чистый дизайн потери производительности? Мы не можем вам этого сказать - это зависит от того, как используется ваш код. Я сильно подозреваю, что снижение производительности будет незначительным, но если вы используете это в замкнутом цикле, это может быть не так. Однако есть только один способ узнать это: измерить, если вас это беспокоит. Лично я, вероятно, просто выбрал бы более чистый дизайн и проверял производительность только тогда, когда казалось, что это становится проблемой.

(Если этот метод обращается к диску или базе данных, кстати, разница почти ограничена , чтобы быть несущественной.)

Кстати, одно предложение: ваш HistoryEntry Тип действительно должен быть изменяемым? Не могли бы вы сделать все свойства доступными только для чтения, поддерживая частные переменные только для чтения?

Просто упомяну точку зрения Уилла - я в некоторой степени с ним согласен. Если эти два метода - только места, где вам нужна эта концепция, я вовсе не уверен, что для этого стоит создавать новый тип. Не из-за аспекта производительности, а просто потому, что вы вводите дополнительную кучу кода без явной выгоды.Здесь демонстрируется ключевое слово - если вы на самом деле используете тот же набор параметров в других местах или можете с пользой поместить логику в класс HistoryEntry , это совсем другое дело.

РЕДАКТИРОВАТЬ: Просто чтобы ответить на вопрос о нескольких целочисленных аргументах - C # 4 разрешит именованные аргументы, которые должны упростить эту задачу. Таким образом, вы можете вызвать:

AddHistoryEntry(userId: 1, companyId: 10);

Чтобы имена были видны с помощью дополнительного класса, требуется один из:

  • Именованные аргументы конструктора из C # 4 (в этом случае вам не лучше, чем с методом)
  • Изменяемые типы ( urgh - это может привести к затруднению отслеживания ошибок, которых не было в исходной версии)
  • Длинные имена статических методов для создания экземпляров ("FromUserAndCompanyId"), которые становятся громоздкими из-за большего количества параметров
  • Изменяемый тип построителя
  • Набор методов "With": new HistoryEntry (). WithCompanyId (...). WithUserId (...) - это затрудняет проверку во время компиляции, которую вы предоставили все необходимые значения.
16
ответ дан 1 December 2019 в 17:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: