Чи варто звести до мінімуму створення безлічі дрібних предметів?


10

Коли ви пишете щось, що створює багато (1000) дрібних об'єктів, ви повинні намагатися мінімізувати це для продуктивності? Особливо, якщо ви не знаєте, на якій системі вона буде працювати, від настільних комп'ютерів низького до високого рівня або навіть мобільних. Для мобільних пристроїв я почув, що створення багатьох об'єктів гальмує продуктивність, хоча я не знаю, наскільки це правда.

У мене є приклад, який добре показує цю ідею. У графічній програмі, скажімо, існує метод, який використовується для всього малювання, яке ідеально називається drawPixel(Point). Тут може бути створено 1000 тисяч очок, і це може повторюватися часто, як у грі, де його можна було б викликати 60+ разів на секунду. Крім того, drawPixel(int x, int y)можна використовувати для мінімізації створення багатьох об'єктів Point.

В об'єктно-орієнтованому дизайні, я думаю, було б краще використовувати Point. Однак використання примітивних типів може підвищити продуктивність. Збільшення продуктивності в більшості випадків може бути незначним, але я не впевнений у таких речах, як мобільні та старі машини. Який приріст від виконання подібних дій і чи варто це враховувати?


У мене важкий час, щоб знайти посилання, щоб підкріпити це, але загалом у Java 8 просто не переживайте про це. Не робіть очевидно дурних речей, але якщо ви свідомо не марнотратні, система повинна спрацьовувати чудово. У Sun / Oracle було близько 20 років, щоб настроїти GC та управління пам’яттю, і вони отримали дуже хороший результат.

@Snowman Я чув, що новіші версії Java роблять краще управління пам’яттю, але проблема, яку я бачу, полягає в тому, що немає гарантії, що користувач не використовує старішу версію. Це частина того, що створило мою турботу.
Стриптиз

1
Спочатку зробіть кілька вимірювань продуктивності. Якщо у вас є проблеми, то подумайте, як оптимізувати. Але, будь ласка, не жертвуйте кодовим обслуговуванням занадто рано, оскільки ви думаєте, що у вас можуть виникнути проблеми з продуктивністю.
Виявлено

2
@Stripies Продуктивність короткотривалих об'єктів Java, на які вже відповіли в " Чи слід уникати створення об'єктів на Java?" . Однак якщо вам коли-небудь доводиться обробляти сотні мільйонів таких об’єктів в секунду, то лише в цей момент перегляньте це питання.
rwong

1
Якщо ви турбуєтесь про старіші версії Java, перевірте це під час встановлення. JVM, достатньо стара, щоб викликати проблеми з управлінням пам'яттю, також має безліч відомих проблем безпеки, тому спонукання користувачів до оновлення робить їм користь. System.getProperty("java.version")(або "java.vm.version") є відправною точкою.
Джеррі Труну

Відповіді:


17

Загалом, ні , вам не слід уникати створення об’єктів, боячись втрати продуктивності. Для цього є кілька причин.

  1. Використання об'єктів - це свого роду сенс використання Java. Превентивне уникання їх - знак того, що рішення про використання Java, можливо, не було правильним для початку.
  2. Проблеми ефективності, як відомо, важко передбачити. Ніколи не вважайте, що щось є вузьким місцем. Завжди міряйте. Інженерія продуктивності майже завжди викликає невеликі зміни в точно потрібному місці. Ви не можете передбачити правильне місце, не вимірюючи більше, ніж можна передбачити ефект ліків без експерименту.
  3. Вартість створення об’єкта сильно завищена. У сучасному JVM це, в основному, збільшує покажчик (а для поколінь, що збирають сміття, вартість управління ним також є тривіальною). В Інтернеті є багато текстів, які радять уникати об'єктів, використовувати об'єднання об'єктів тощо. Іноді ця порада була правильною у 90-х роках; сьогодні це здебільшого застаріло. Ви навряд чи наберетеся достатньої продуктивності, щоб виправдати додаткову вартість розробки та складність, введену, уникаючи Об'єктів або керуючи ними самостійно.

Однак, є місця, де щось робити в об'єкт не має сенсу починати. Передача двох координат у порядок малювання може бути таким випадком: пара координат не має самостійного існування, вона не має ідентичності, вона використовується лише один раз, а потім негайно відкидається тощо.

Якщо це так, то обов'язково йдіть вперед і пройдіть два ints, а не загортайте їх в об'єкт. Суть ООП не в тому, що все повинно бути об'єктом. Справа в тому, що об’єкти полегшують розробку в місцях, де вони є природним рішенням проблеми представлення даних. Не уникайте предметів, де вони мають сенс - не вводьте їх там, де їх немає.


2

Розмірковуючи про вплив на ефективність, перш ніж писати код, слід вважати, що ви не знаєте, що робите.

На об'єктах у Java є дуже малий простір, що знаходиться над головою, порівняно з примітивом. Чим дрібніше ваші об'єкти, тим більший відсоток накладних витрат. Однак я давно дізнався, що речі, які подвоюються n, - це ніщо в порівнянні з речами, що множать n на n.

Тож як так, ви можете доопрацювати якусь систему, яка мала наполовину вплив або навіть четверту, запитайте себе, чому ви насправді хвилюєтесь. Складні рішення цієї проблеми не будуть сприйняті добре. Тим більше, що занурення в такий код буде заплутаним. Розгублені програмісти пишуть поганий код. Вони записують n разів n код, який повинен бути n log n код. І їм потрібно більше часу.

Тепер, якщо ви можете врятувати мені простір якоюсь хитрістю, яка впишеться в приємну скриньку, про яку я не повинен заглядати всередину більшу частину часу, коли ми можемо поговорити. Якщо це коробка, я можу помінятись на іншу коробку, коли ця коробка буде працювати краще, я навіть можу заплатити за неї.


2

У налаштуваннях продуктивності, які я робив ( приклад ), управління пам'яттю дуже легко бути головним винуватцем. Мені байдуже, наскільки шалено вони настроїли нового оператора та збирач сміття, найшвидший обчислення - це не обчислення. Тож якщо я знаходжу, що менеджер пам'яті займає непоганий відсоток часу, і я не можу уникати створення об’єктів , то знаходжу спосіб їх повторного використання, а не постійно створювати нові.

Я роблю це лише в тому випадку, якщо мені доведеться робити предмети. Що стосується графіки, зазвичай я цього не роблю. ІМХО, графіку слід малювати , а не будувати . Звичайно, можна сказати, що малюнок складається з точок, ліній, що їх з'єднують, багатокутників, тексту тощо. Це не означає, що у вас немає альтернативи робити об’єкти з них, перш ніж їх малювати . Я просто малюю їх.

Існує метод Paint. Я перекриваю це, малюю все до растрової карти, а потім блокую перенести це на екран. Це виглядає миттєво. Для введення миші є методи переосмислення, виявлення клацання, перетягування, будь-що.

OOP - хороша ідея з певних причин. Ці причини застосовуються не у всіх ситуаціях.


Я згоден, але я також погоджуюся з усіма іншими, що тестування - це єдиний спосіб точно знати. Будьте впевнені, у вас є специфікації, які роблять це простим / очевидним способом, перш ніж оптимізувати його ... але я згоден, що нове все ще може бути проблемою.
Білл К

2

Вперед та використовуйте невеликі асигнування. Сучасні менеджери пам'яті, особливо оптимізований менеджер об'єктів Java, надзвичайно ефективні. Збережіть основну оптимізацію продуктивності робочої програми.

Надзвичайно ймовірно, що загальна ефективність буде достатньою. Якщо ви виявите, що це не так, то і лише потім проаналізуйте продуктивність коду. За довгу кар’єру розробки програмного забезпечення я дізнався, що вузькі місця майже ніколи не очікуються.

Одного разу мені довелося, що член команди витратив кілька днів, роблячи пошук об’єкта на 20 разів швидше. Успіху! Однак найкраща загальна швидкість у фактичному використанні була виміряна в сотих відсотках. Зміна була негайно вимкнена, оскільки для збільшення швидкості потрібно було більше розподілу пам'яті на кожного члена.


1

Це просто: Якщо вам потрібно 1000 маленьких об'єктів, ви створюєте 1000 маленьких об'єктів і не турбуєтесь про це. Якщо вам потрібно 100 маленьких об’єктів, то створювати 1000 малих об’єктів - дурно - створюйте ті, які вам потрібні, а не більше.

Якщо ви турбуєтесь про продуктивність (і якщо ви також не турбуєтесь про продуктивність), ви повинні мати будь-яку функціональність, записану один раз в одному місці, що робить весь ваш код простішим і легшим для розуміння. Тоді якщо у вас є проблеми з продуктивністю, то вимірювання може показати вам, що є одне місце, де відбувається проблема продуктивності, що полегшує роботу, і лише одне місце, де вам потрібно змінити його. Або вимірювання показує, що це одне місце не викликає жодних проблем, тож ви закінчили.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.