Безопасно ли вообще предполагать, что toString () имеет низкую стоимость? - PullRequest
14 голосов
/ 18 сентября 2008

Вы обычно предполагаете, что toString () для любого данного объекта имеет низкую стоимость (то есть для регистрации)? Я делаю. Это предположение верно? Если это имеет высокую стоимость, должно ли это быть обычно изменено? Каковы веские причины для создания метода toString () с высокой стоимостью? Единственный раз, когда меня беспокоит стоимость toString, - это когда я знаю, что это какая-то коллекция со многими участниками. От: http://jamesjava.blogspot.com/2007/08/tostring-cost.html

Обновление: еще один способ выразить это: вы обычно изучаете стоимость вызова toString для любого данного класса перед его вызовом?

Ответы [ 17 ]

38 голосов
/ 18 сентября 2008

Нет, это не так. Поскольку ToString () может быть перегружен кем угодно, они могут делать все что угодно. Разумно предположить, что ToString () ДОЛЖНА иметь низкую стоимость, но если ToString () обращается к свойствам, которые выполняют «отложенную загрузку» данных, вы можете даже попасть в базу данных внутри вашей ToString ().

19 голосов
/ 18 сентября 2008

Кажется, стандартная библиотека Java написана с целью снижения стоимости вызовов toString. Например, у Java-массивов и коллекций есть методы toString, которые не перебирают свое содержимое; чтобы получить хорошее строковое представление этих объектов, вы должны использовать Arrays.toString или Collections.toString из пакета java.util.

Точно так же даже объекты с дорогими методами equals имеют недорогие вызовы toString. Например, класс java.net.URL имеет метод equals, который использует подключение к Интернету для определения, действительно ли два URL равны, но у него все еще есть простой метод toString с постоянным временем.

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

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

9 голосов
/ 18 сентября 2008

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

К счастью, существует множество профилировщиков с открытым исходным кодом для Java .

5 голосов
/ 18 сентября 2008

Вы обычно предполагаете, что toString () для любого данного объекта имеет низкую стоимость? Я делаю.

Зачем ты это делаешь? Профиль ваш код, если вы сталкиваетесь с проблемами производительности; это сэкономит вам много времени, работая над ошибочными предположениями.

3 голосов
/ 18 сентября 2008

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

1 голос
/ 18 сентября 2008

Я думаю, что вопрос имеет недостаток. Я даже не предполагал, что toString () напечатает полезную часть данных. Итак, если вы начнете с этого предположения, вы знаете, что должны проверить его до вызова и можете оценить его «стоимость» в каждом конкретном случае.

1 голос
/ 18 сентября 2008

Мой прагматичный ответ будет таким: да, вы всегда предполагаете, что вызов toString () дешев, если только вы не делаете их огромное количество. С одной стороны, крайне маловероятно, что метод toString () будет дорогим, а с другой стороны, крайне маловероятно, что вы столкнетесь с проблемами, если это не так. Я обычно не беспокоюсь о таких проблемах, потому что их слишком много, и вы не получите никакого написанного кода;).

Если вы сталкиваетесь с проблемами производительности, все открыто, включая производительность toString (), и вы должны, как рекомендует Shog9, просто профилировать код. Java Puzzlers показывают, что даже Sun написал несколько довольно неприятных конструкторов и методов toString () в своих JDK.

1 голос
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

Обычно я считаю toString () дешевым, когда использую его для простых объектов, таких как целочисленные или очень простые структуры. Однако, когда применяется к сложным объектам, toString () немного дерьмово. Есть две причины для этого. Во-первых, сложные объекты, как правило, содержат другие объекты, поэтому один вызов toString () может каскадно объединить множество вызовов toString () для других объектов, а также верхний предел объединения всех этих результатов. Во-вторых, не существует «стандарта» для преобразования сложных объектов в строки. Один вызов toString () может выдать одну строку значений, разделенных запятыми; другая, гораздо более многословная форма. Только проверяя это, вы можете узнать.

Таким образом, мое правило заключается в том, что toString () на простых объектах, как правило, безопасно, но на сложных объектах подозрительно, пока не проверено.

0 голосов
/ 18 сентября 2008

Поскольку вы ставите «в общем» в своем вопросе, я бы сказал, да. Для большинства объектов не будет дорогостоящей перегрузки ToString. Определенно может быть, но, как правило, не будет.

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