Я боюся, що я тут роблю неправильну справу, якщо так видаліть мене і вибачаюся. Зокрема, я не бачу, як я створюю акуратні невеликі анотації, які створили деякі люди. Однак у мене є багато питань / зауважень щодо цієї теми.
1) Коментований елемент у псевдокоді в одній із популярних відповідей
result = query( "select smurfs from some_mushroom" );
// twiddle fingers
go_do_something_with_result( result );
є по суті неправдивим. Якщо нитка обчислюється, то це не великі пальці, вона робить необхідну роботу. Якщо, з іншого боку, він просто чекає завершення IO, то він не використовує час процесора, вся суть інфраструктури управління потоком в ядрі полягає в тому, що процесор знайде щось корисне. Єдиний спосіб "закрутити пальці", як тут пропонується, - створити цикл опитування, і ніхто, хто закодував справжнього веб-сервера, недостатньо невмілий для цього.
2) "Нитки важкі", має сенс лише в контексті обміну даними. Якщо у вас є, по суті, незалежні потоки, як це має місце при обробці незалежних веб-запитів, то введення ниток тривіально просте, ви просто кодуєте лінійний потік, як впоратися з однією роботою, і сидите, знаючи, що вона буде обробляти кілька запитів, і кожен буде ефективно незалежним. Особисто я б задумався, що для більшості програмістів вивчення механізму закриття / зворотного виклику є складнішим, ніж просто кодування версії з низу вниз. (Але так, якщо вам доведеться спілкуватися між потоками, життя стає дуже важким дуже швидко, але тоді я не переконаний, що механізм закриття / зворотного виклику дійсно змінює це, він просто обмежує ваші варіанти, тому що такий підхід все ще досягається за допомогою потоків У будь-якому випадку, це "
3) Поки ніхто не представив жодних реальних доказів того, чому один конкретний тип контекстного перемикання забирає більше чи менше часу, ніж будь-який інший тип. Мій досвід створення багатозадачних ядер (в невеликих масштабах для вбудованих контролерів, нічого такого фантазійного, як "справжня" ОС) говорить про те, що це було б не так.
4) Усі ілюстрації, які я бачив на сьогоднішній день, що мають на меті показати, наскільки швидше Вузол, ніж інші веб-сервери, страшенно хибні, однак вони хибні таким чином, що це опосередковано ілюструє одну перевагу, яку я б точно прийняв за Node (і це аж ніяк несуттєво). Вузол не виглядає так, як він потребує (навіть навіть не дозволяє) налаштування. Якщо у вас є різьбова модель, вам потрібно створити достатню кількість ниток для обробки очікуваного навантаження. Зробіть це погано, і у вас виявиться погана робота. Якщо ниток занадто мало, то процесор простоює, але не в змозі приймати більше запитів, створити занадто багато потоків, і ви будете витрачати пам’ять ядра, а у випадку середовища Java ви також будете витрачати основну пам'ять купи . Тепер для Java витрачаючи купу - це перший, найкращий спосіб налагодити продуктивність системи, тому що ефективне збирання сміття (зараз це може змінитися з G1, але, здається, присяжні все ще залишаються з цього приводу, як мінімум, на початку 2013 року) залежить від того, щоб мати багато запасної маси. Отже, є проблема, налаштуйте її на занадто мало потоків, у вас непрацюючі процесори та погана пропускна спроможність, налаштуйте їх на занадто багато, і це зменшиться іншими способами.
5) Є ще один спосіб, яким я приймаю логіку твердження, що підхід Вузла «швидший за дизайном», і це ось що. Більшість моделей потоків використовують модель контекстного перемикача з часовим нарізанням, шарувату поверх більш підходящої (попередження про оцінку вартості :) та більш ефективної (не судження про значення) попереджувальної моделі. Це трапляється з двох причин, по-перше, більшість програмістів, здається, не розуміють пріоритетного пріоритету, а по-друге, якщо ви навчитеся нарізування в середовищі Windows, часові накладки є, вам це подобається чи ні (звичайно, це підсилює перший пункт Перш за все, перші версії Java використовували попередження щодо пріоритету при впровадженні Solaris та синхронізації в Windows. Оскільки більшість програмістів не розуміли і скаржилися, що "в Соляріс не працює нитка". вони скрізь міняли модель на часовий шрифт). У будь-якому разі, підсумок полягає в тому, що часове оформлення створює додаткові (і потенційно непотрібні) контекстні комутатори. Кожен контекстний перемикач займає час процесора, і цей час фактично вилучається з роботи, яку можна виконати на реальній роботі. Однак кількість часу, вкладеного в перемикання контексту через часове укладання часу, не повинна становити більше, ніж дуже малий відсоток від загального часу, якщо не трапиться щось досить чуже, і я не маю жодної причини, щоб я очікував, що це буде так простий веб-сервер). Отже, так, надлишкові контекстні комутатори, що беруть участь у часовій формі, неефективні (а це не відбувається в і цей час фактично усувається від роботи, яку можна виконати на справжній роботі. Однак кількість часу, вкладеного в перемикання контексту через часове укладання часу, не повинна становити більше, ніж дуже малий відсоток від загального часу, якщо не трапиться щось досить чуже, і я не маю жодної причини, щоб я очікував, що це буде так простий веб-сервер). Отже, так, надлишкові контекстні комутатори, що беруть участь у часовій формі, неефективні (а це не відбувається в і цей час фактично усувається від роботи, яку можна виконати на справжній роботі. Однак кількість часу, вкладеного в перемикання контексту через часове укладання часу, не повинна становити більше, ніж дуже малий відсоток від загального часу, якщо не трапиться щось досить чуже, і я не маю жодної причини, щоб я очікував, що це буде так простий веб-сервер). Отже, так, надлишкові контекстні комутатори, що беруть участь у часовій формі, неефективні (а це не відбувається внитки ядра, як правило, btw), але різниця становитиме кілька відсотків пропускної здатності, а не виду цілих чисельних факторів, що маються на увазі у формулі заявок на продуктивність, які часто маються на увазі для Node.
У будь-якому випадку, вибачте за те, що все це довге і розгублене, але я дійсно відчуваю, що поки що обговорення нічого не довело, і мені було б приємно почути від когось у будь-якій з цих ситуацій:
а) реальне пояснення того, чому Node повинен бути кращим (за межами двох сценаріїв, які я окреслив вище, перший з яких (погана настройка), я вважаю, є реальним поясненням для всіх тестів, які я бачив до цього часу. ([редагувати ] насправді, чим більше я думаю про це, тим більше мені цікаво, чи пам'ять, яка використовується великою кількістю стеків, може бути тут значною. Розміри стеків за замовчуванням для сучасних потоків, як правило, досить величезні, але пам'ять, виділена система подій на основі закриття буде лише тим, що потрібно)
б) реальний орієнтир, який фактично дає справедливий шанс потоковому серверу на вибір. Принаймні таким чином, я повинен був би перестати вірити, що претензії по суті є помилковими;> ([редагувати] це, мабуть, досить сильніше, ніж я мав намір, але я вважаю, що пояснення, надані для вигоди від продуктивності, в кращому випадку є неповними, і показані орієнтири нерозумні).
Ура, Тобі
select()
відбувається швидше, ніж контекстові потоки.