Як Swift може бути настільки швидшим, ніж Objective-C у цих порівняннях?


115

Apple запустила свою нову мову програмування Swift на WWDC14 . У презентації вони здійснили порівняння продуктивності між Objective-C та Python. Далі наведено зображення одного з їх слайдів, порівняння цих трьох мов, які виконують деякий складний тип об'єкта:

введіть тут опис зображення

Був ще більш неймовірний графік порівняння продуктивності за допомогою алгоритму шифрування RC4 .

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

  1. Як нова мова програмування може бути набагато швидшою?
  2. Чи спричинені результати Objective-C поганим компілятором чи є щось менш ефективне в Objective-C, ніж Swift?
  3. Як би ви пояснили підвищення на 40%? Я розумію, що збирання сміття / автоматизований контрольний контроль може призвести до додаткових накладних витрат, але це багато?

13
@MathewFoscarini Obj-C переходить до асемблера, але у нього є дорогий механізм відправки повідомлення об'єкта. Для більшості роботи графічного інтерфейсу це не має значення, але для їх сортування важливо багато.
стипендіати

17
Порівняння з Python є справжньою рукою у голові.
asthasr

9
@syrion маркетинг, і мова, схоже, запозичує синтаксис python (подібно голангу). Вони намагаються сказати "ей, розробники python, ви можете написати щось не надто іноземне на mac, і це буде ТАК набагато швидше, навіть швидше, ніж об'єктив C, на який ви ніколи не потрапляли"

4
@MichaelT Я це розумію, але все одно дивно. Кожен, хто що-небудь знає про мови, зрозуміє, що Python, як інтерпретована мова, просто не перебуває в тому самому контрольному плані, що і Objective-C, або інших мовах, що складаються (для більшості завдань). Використання його в якості еталону є дивним.
asthasr

7
Вони, мабуть, мають на увазі час, необхідний для написання коду ...
Лукас Едер

Відповіді:


62

По-перше, (IMO) порівнювати з Python майже безглуздо. Тільки порівняння з Objective-C має сенс.

  • Як нова мова програмування може бути набагато швидшою?

Objective-C - повільна мова. (Тільки C частина швидка, але це тому, що це C) Це ніколи не було надзвичайно швидко. Це було достатньо швидко для їх (Apple) цілей і швидше, ніж їх старіші версії. І це було повільно, тому що ...

  • Чи є Objective-C результатом поганого компілятора чи є щось менш ефективне в Objective-C, ніж Swift?

Objective-C гарантував, що кожен метод буде динамічно відправлений. Немає статичної відправки взагалі. Це унеможливило подальшу оптимізацію програми Objective-C. Добре, можливо, технологія JIT може допомогти, але AFAIK, Apple справді ненавидять непередбачувані характеристики продуктивності та термін експлуатації об'єкта. Я не думаю, що вони прийняли будь-які речі з JIT. У Swift немає такої динамічної гарантії відправки, якщо ви не введете якийсь спеціальний атрибут для сумісності Objective-C.

  • Як би ви пояснили підвищення на 40%? Я розумію, що збирання сміття / автоматизований контрольний контроль може призвести до додаткових накладних витрат, але це багато?

GC або RC тут не мають значення. Свіфт також в основному використовує RC. Ніякої GC немає, і також не буде, якщо не буде величезного архітектурного стрибка в технології GC. (IMO, це назавжди) Я вважаю, що у Свіфта є набагато більше місця для статичної оптимізації. Особливо низькі алгоритми шифрування, оскільки вони, як правило, покладаються на величезні числові обчислення, і це величезний виграш для мов статичного відправлення.

Насправді я був здивований, тому що 40% здається занадто малим. Я очікував набагато більше. Так чи інакше, це початковий випуск, і я думаю, що оптимізація не була основною проблемою. Свіфт навіть не є повнофункціональним! Вони зроблять це краще.

Оновлення

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

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

У всякому разі, я підозрюю, що вимога пропускної здатності GC завжди краща, ніж RC. Більшість накладних витрат RC відбувається від операції підрахунку перезарядки та блокування для захисту змінної числа перерахунку. І реалізація RC зазвичай забезпечує спосіб уникнути підрахунку операцій. У Objective-C є __unsafe_unretainedі в Swift (хоча це все ще мені дещо незрозуміло) unowned. Якщо вартість операції підрахунку повторних підрахунків неприйнятна, ви можете спробувати вибірково відмовитися від них за допомогою механіки. Теоретично ми можемо змоделювати майже унікальний сценарій власності, використовуючи неагресивні посилання дуже агресивно, щоб уникнути накладних витрат на RC. Також я сподіваюся, що компілятор може автоматично усунути деякі очевидні непотрібні операції RC.

На відміну від RC-системи, AFAIK, часткове відмовлення від еталонних типів не є можливим для системи GC.

Я знаю, що існує багато випущених графічних і ігор, які використовують систему на основі GC, а також знаю, що більшість із них страждає від детермінізму. Не тільки для характеристик продуктивності, але й управління об'єктом життя. Unity в основному написано на C ++, але крихітна частина C # викликає всі дивні проблеми з продуктивністю. HTML-гібридні програми та все ще страждають від непередбачуваних спайок у будь-якій системі. Широко використовуваний не означає, що це найкраще. Це просто означає, що це легко і популярно людям, які не мають багатьох варіантів.

Оновлення 2

Знову, щоб уникнути зайвих аргументів чи дискусій, я додаю ще кілька деталей.

@Asik представив цікаву думку про шипи GC. Ось ми можемо розглядати підхід ціннісного типу скрізь як спосіб відмови від GC. Це досить привабливо і навіть можливо в деяких системах (наприклад, суто функціональний підхід). Я згоден, що це приємно в теорії. Але на практиці це кілька питань. Найбільша проблема полягає в тому, що часткове застосування цього фокусу не забезпечує справжніх характеристик, що не містять шипів.

Тому що проблема з затримкою - це завжди все або нічого . Якщо у вас один шип кадру протягом 10 секунд (= 600 кадрів), то вся система явно виходить з ладу. Мова йде не про те, як краще, чи гірше. Це просто пройти чи провалити. (або менше 0,0001%) Тоді де джерело шипу GC? Це поганий розподіл навантаження GC. І це тому, що GC в принципі недетермінований. Якщо ви робите будь-яке сміття, то він активує GC, і з часом відбудеться шип. Звичайно, в ідеальному світі, де навантаження GC завжди буде ідеальною, цього не відбудеться, але я живу в реальному, а не уявному ідеальному світі.

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

На відміну від GC, RC є принципово детермінованим, і вам не доведеться використовувати цю божевільну оптимізацію (суто ціннісний тип) лише для уникнення шипу. Що вам потрібно зробити, це відстежити та оптимізувати частину, яка спричиняє шип. У системах RC спайк - це проблема місцевого алгоритму, але в системах GC шипи - це завжди глобальна система.

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


4
Збір сміття, особливо покоління, зазвичай значно швидший, ніж довідковий підрахунок.
Ян Худек

9
@JanHudec Ваша значно швидша просто безглузда в графічному полі в реальному часі. Ось чому я зазначаю, що в GC потрібен величезний стрибок . Покоління GC навіть не є теоретичним і практичним.
Eonil

5
Швидше і без шипа - це абсолютно ортогональні категорії. Покоління сміттєзбірників швидше . Вони не є шипами.
Ян Худек

4
Те, що ви говорите, - пропускна здатність . Швидше завжди був невиразним терміном і може означати що завгодно за контекстом. Якщо ви хочете сперечатися про значення термінів, вам слід скористатися більш точним терміном, а не швидше, особливо з урахуванням поточного контексту - графіки в реальному часі.
Еоніл

11
@JanHudec: На мобільних пристроях або будь-яких пристроях із обмеженими ресурсами GC не є значно швидшим і насправді є основною частиною проблеми.
Мейсон Уілер

72

Будучи в 3,9 рази швидшим за python, мова, яка стабільно втрачає більшість показників за значним запасом (нормально, це нарівні з Perl, Ruby та PHP; але втрачає все, що статично набрано), не має чим похвалитися.

Гра з орієнтирами показує програми C ++, які більш ніж на порядок швидші, ніж програми python у більшості випадків. Це не набагато краще, якщо порівнювати з Java, C # (на Mono), OCaml, Haskell і навіть Clojure, які статично не набрані.

Тож справжнє питання полягає в тому, як це Objective-C лише в 2,8 рази швидше, ніж python. Мабуть, вони ретельно вибрали орієнтир, де повільна повністю динамічна відправка ObjC сильно шкодить. Будь-яка статично набрана мова повинна вміти робити краще. У складному об'єктному сортуванні існує багато викликів методів для порівняння об'єктів, і власне порівняння, ймовірно, було не дуже складним. Отже, якщо Swift користується хоч якоюсь перевагою інформації про тип, вона може легко зробити краще при викликах методу, і немає інших операцій, в яких ObjC міг би бути кращим.

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


13
Я не зовсім розумію сенс цієї відповіді. Ви відповідаєте "як швидше швидше", кажучи, що "орієнтири недосконалі"? Це те, про що ти робиш? Я не бачу, як це відповідає на запитання.
Брайан Оуклі

15
@BryanOakley: Я не думаю, що показники є недоліками, але, безумовно, слід враховувати можливість того, що вони вибрали один тест, де Swift був швидшим.
Ян Худек

23
Цілком можливо, що відповідь на тему "Як швидше швидкий?" може бути "Насправді це не так", @BryanOakley; в цьому полягає суть, яку я отримую з відповіді Яна. "Брехня, чорт брехня, і статистика", зрештою.
Джош Касвелл

4
Ще деякий час ми орієнтували Codename One, що працює на iOS, і наша реалізація Java була набагато швидшою, ніж Objective-C codenameone.com/blog/… Ян правильно, динамічна розсилка дійсно повільна, якщо вони ще трохи покращили їх, то деякі орієнтири будуть показують величезне поліпшення. Якщо вони покращать ARC навіть на частку (завдяки кращому аналізу коду), вони можуть позбутися смішної кількості складності. Чим більше обмежена мова, тим більше компілятор може зробити для оптимізації (див. Java), і Swift додає обмеження.
Шай Алмог

7
Відповідь Яна - ідеальна відповідь на Q1 та, ймовірно, Q2. Коли я побачив орієнтири маркетингової події як основну, я подумав: "Нічого собі, лише 1,3 рази у вибраному найкращому випадку. Яким будемо середній результат? 0,3х?"
Амін Негм-Авад

5

Objective-C динамічно розсилає кожен виклик методу.

Гіпотеза: Тест використовує статичну типізацію, щоб компілятор Swift виводив compareметод пошуку з sortциклу. Для цього потрібне обмеження вузького типу, яке дозволяє лише об'єкти Complex в масиві, а не підкласи Complex.

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

Гіпотеза: Швидкий оптимізує виклик підрахунку посилань із циклу.

Гіпотеза: Тест Swift використовує складну структуру замість об'єкта Objective-C, тому для порівняння сортування не потрібні диспетчеризації методів динамічного методу (оскільки це неможливо підкласифікувати) або роботи підрахунку посилань (оскільки це тип значення).

(У Objective-C ви можете повернутися до C / C ++ для продуктивності до тих пір, поки вони не включатимуть об'єкти Objective-C, наприклад сортувати масив С.)


3

Чесно кажучи, якщо б вони не випустили джерело на тести, які вони використовують, я б не довіряв тому, що Apple має сказати з цього приводу. Пам’ятайте, це компанія, яка перейшла з КПК на Intel на основі енергетичних проблем, коли 6 місяців раніше вони говорили, що Intel смоктала і насправді зажигала зайчика Intel у рекламі. Я хотів би бачити важкий незаперечний доказ того, що Свіфт швидше, ніж ObjC, у кількох категоріях, ніж просто сортування.

Крім того, ви повинні поставити під сумнів будь-які статистичні дані, оприлюднені на WWDC, оскільки вони мають запах маркетингу по всьому.

На все це сказано, що я не проводив жодних тестів між swift та ObjC, але, наскільки я знаю, у Swift є власні розширення LLVM IR, і можливо, що в час компіляції робиться більше оптимізації, ніж у ObjC.

Повне розкриття інформації: Я пишу компілятор Swift з відкритим кодом, який знаходиться за адресою https://ind.ie/phoenix/

Якщо хтось хотів би допомогти переконатися, що Swift доступний не лише на апаратному забезпеченні Apple, дайте мені знати, і я би радий включити вас.


2
це більше схоже на ретельний коментар, див. Як відповісти
gnat

2
Чи краще зараз? :)
greg.casamento

0

Я боровся за допомогою підручника «Свіфт», і мені здається, що Свіфт більше приземлений (змушує мене думати про Visual Basic) з меншою «об'ємною ітифікацією», ніж «Ціль-С». Якби вони брали до уваги C або C ++, я припускаю, що останні виграли б, оскільки вони ще більше часу на компіляцію.

У цьому випадку я припускаю, що Objective-C є жертвою об'єктно-орієнтованої чистоти (і накладних витрат).


13
Зробити тест "складного сортування об'єктів" було б трохи складно в такій мові, як C, яка не має вбудованої реалізації об'єктів. Враховуючи, що аудиторія для цієї бесіди, ймовірно, 100% програмістів Objective-C, порівняння з мовою на зразок C ++ теж не має особливого сенсу. Суть швидкого не в "ей, це найбільша мова коли-небудь!" але швидше "ей, це швидше, ніж мова, яку ви зараз використовуєте для розробки OSX / iOS".
Брайан Оуклі

10
C має ідеально тонкий, qsortякий дозволить складно сортувати об'єкти; він просто використовує зворотний виклик, який розуміє об'єкти, що знаходяться під рукою. Я підозрюю, що C ++ відсутній, тому що std::sortможе бентежити Свіфта. (Оскільки це шаблон, компілятор C ++ може значно оптимізувати його, аж до розгортання циклу.)
MSalters

@MSalters: Я повністю з вами згоден. І C, і C ++ мають можливості випередити Swift. Чи вдалося б отримати виконаний тест. Я більше ніж готовий виконати той самий тест із Swift, Objective-C, C ++ та C.
Painted Black

@BryanOakley також: "Ця мова вимагає менше квадратних дужок!"
Нік Бедфорд

1
Ця відповідь взагалі не тримає води і жахливо вводить в оману. OO насправді не повільний, адже найшвидшими системами, які ви знайдете навколо, будуть C ++, Java та C #, а стиль (сильно OO чи ні) програмування матиме дуже мало спільного з швидкістю, що виходить, якщо у вас справді немає неправильний код.
Білл К
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.