Коли оцінка короткого замикання погана?


12

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

Зараз я починаю роботу над проектами, для яких потрібен VB.net, і я бачу, що це забезпечує обидва способи в плані AND і ANDALSO . Перший не має короткого замикання, а другий -.

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

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

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



Відповіді:


5

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

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

В інших випадках ви не хочете оцінювати жоден із решти термінів, якщо попередня оцінка повертає помилкову.

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

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

ANDBSO VB чіткий і, здається, намагається зробити цю практику більш прийнятною.

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


4
Хоча фактично правильно, це не чудовий дизайн.
Роберт Харві

2
@RobertHarvey, я не можу написати систему управління, яка не має побічних ефектів, і я не можу правильно керувати системою, якщо не реагую на результати. Іншими словами, здолайте це;).
jwdonahue

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

3
@jwdonahue Добре використовувати "великі слова", якщо ризик плутанини низький. Ризик плутанини та відсутніх конкретних нюансів блоку коду, як це, надзвичайно великий і може бути катастрофічним для логіки. Ніколи не добре змусити розробника читання думати дуже важко.
jpmc26

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

20

Мабуть, ваше питання полягає не в тому, що коротке замикання добре чи погано в цілому, а про те, чому VB.NET надає операторам з і без нього. Зважаючи на це, відповідь на

коли погана оцінка короткого замикання?

просто: коли це порушує зворотну сумісність .

Гаразд, тепер ви можете сказати, що VB.NET не дуже сумісний із старим VB6 або VBA, проте принаймні певні частини мови є. Рішення Microsoft зберегти стару семантику AND та OR (без короткого замикання) зробило величезну категорію помилок, що рідше виникають при перенесенні старих програм VB на VB.NET.

З іншого боку, дизайнери мови VB.NET, напевно, поділилися вашою думкою про те, що коротке замикання є хорошою справою. Коли я правильно пам’ятаю, перші версії до випуску VB.NET надавали операторам AND або OR коротке замикання, але відгуки розробника повинні були бути такими поганими, що MS відкликали це рішення до появи VB.NET 1.0. Тож дизайнери вирішили застосувати його як нові ключові слова, так ANDALSOі ORELSEкомпроміс між зворотною сумісністю та корисністю.

ІМХО це було вдале рішення. Мені довелося перенести кілька старих програм за останнє десятиліття, і не потребуючи важкого аналізу впливу для кожного логічного виразу, включаючи AND та / або АБО (каламбур), це завдання стало набагато простішим та економічнішим. З іншого боку, коли мені доводиться писати новий логічний вираз у VB.NET, моїм вибором для операторів за замовчуванням є форми короткого замикання, тобто до чого я звик із C, C ++, C # тощо, і це дозволяє мені потрібно написати кілька ідіом у більш стислій формі (навіть якщо ANDALSO потребує 4 символів більше, щоб набрати).

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


Гаразд, це кваліфікується як скандал, а посилання на Марсіанські навушники зовсім не пов'язані.
jwdonahue

6
@jwdonahue: Я поняття не маю, чому ви вважаєте, що це хитрість, навпаки. А стаття про Марсіанські гарнітури розповідає про те, чому деякі дизайнерські рішення в розробці програмного забезпечення, прийняті кілька десятиліть тому, не можуть бути легко скасовані після того, як компонент або мова чи API досягли певної кількості користувачів. Невже аналогію насправді не зрозуміти? У минулому VB6 був дуже популярним, і я впевнений, що досі сотні тисяч компаній світу мають найважливіші додатки для роботи в VB6 або VBA.
Док Браун

Я не зовсім розумію, як насправді підходить стаття про "марсіанські верстви". Для забезпечення сумісності між X і Y (наприклад, гайки та болти) необхідно встановити окремі стандарти для X і Y, щоб гайка з гіршим випадком вмістила болт трохи гірший, ніж зазначено, і навпаки. Потрібно спробувати написати характеристики, щоб уникнути того, щоб гайки або болти були непотрібними дорогими або не мали зайвого нахилу між гайками та болтами, але, якщо вказати обидві половинки окремо, можна забезпечити сумісність набагато надійніше, ніж намагатися мати одну специфікацію служити обом сторонам.
supercat

3
@supercat: мова йде про те, що вже існують і використовуються трилійони гайок (або рядків коду VB6), і тепер болти (або в цьому випадку компілятор VB) будуть замінені новим поколінням. Якщо наявні гайки підходять лише до неметрічних болтів, то не тільки економічно робити новіші болти метричними системами.
Док Браун

tl; dr: VB - це діалект BASIC, мова датується 1964 р., а в BASIC Andоперація не має короткого замикання, ні в SQL (1974), ні в FORTRAN (1956), ні в Pascal (1970).
Бен

3

коли погана оцінка короткого кола?

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


1

Caveat : Це трохи езотерично, оскільки майже у всіх випадках розробники не повинні турбуватися про це. Але ... може бути хіт ефективності завдяки умовному оцінюванню, оскільки він створює розгалуження у виконанні. Некоротке замикання не розгалужується і є більш передбачуваним.

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


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

@jwdonahue Я не розумію вашої точки зору. Вибачте.
JimmyJames

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

1
@jwdonahue Звичайно, але кожне коротке замикання - це додаткова гілка. У певних сценаріях виконання двох виразів (наприклад) швидше, ніж перевірка результату першого перед виконанням другого, навіть якщо часто трапляється, що другий не має значення. Знову ж таки, це рідко важливо. Випадок, який хтось зробив мені для цього, стосувався таких речей, як матричне множення, де у вас багато простих оцінок.
JimmyJames

1
Я оновив свою відповідь з кредитом до вас.
jwdonahue

0

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

C і C ++ мають побітові операції & і | які на практиці дають вам операції без короткого замикання. І компілятори вільно оцінюють будь-який спосіб, який їм подобається, якщо це не має помітних змін.


@ Дедуплікатор: Як зазначалося, Паскаль не визначав, чи використовує І / АБО оцінку короткого замикання. Це означає "не знати".
supercat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.