Когда предпочесть `and` над` andal`` в контрольных тестах - PullRequest
24 голосов
/ 17 мая 2011

Мне любопытно, почему запятая ‹,› является сокращением для and, а не andalso в защитных тестах.

Поскольку я бы назвал себя «родным Си», я не вижу каких-либо недостатков в логической оценке короткого замыкания.

Я скомпилировал некоторый тестовый код, используя флаг to_core, чтобы увидеть, какой код действительно генерируется. Используя запятую, я вижу, как вычисляются значение слева, а справа и значение, а также значение «и». С andalso у вас есть блок case внутри блока case и нет вызова на erlang:and/2.

Я не проводил тесты, но, полагаю, вариант andalso является более быстрым.

Ответы [ 4 ]

24 голосов
/ 17 мая 2011

Чтобы углубиться в прошлое:

  • Первоначально в охранниках было только , разделенные тесты , которые оценивались слева направо, пока либо тамбольше не было, и охранник преуспел, или испытание не прошло, и охранник в целом провалился.Позже ; был добавлен, чтобы разрешить альтернативным охранникам в том же пункте.Если охранники оценивают обе стороны , перед тестированием, то кто-то ошибся по пути.Пример @ Кея подразумевает, что они идут слева направо, как и должны.

  • Булевы операторы были разрешены только позже в страже.

  • and вместе с or, xor и not является логическим оператором и не предназначен для управления.Все они строгие и вначале оценивают свои аргументы, как арифметические операторы +, -, * и '/'.Также существуют строгие логические операторы в Си.

  • Короткозамкнутые операторы control andalso и orelse были добавлены позже для упрощения некоторого кода.Как вы уже сказали, компилятор расширяет их до вложенных выражений case, поэтому при их использовании нет выигрыша в производительности, только удобство и ясность кода.Это объясняет результирующий код, который вы видели.

  • NB в охранниках есть тесты , а не выражения.Существует небольшая разница, которая означает, что при использовании and и andalso эквивалентно ,, использование orelse не эквивалентно ;.Это оставлено на другой вопрос.Подсказка: все дело в неудаче.

Так что и and, и andalso имеют свое место.

7 голосов
/ 17 мая 2011

Адам Линдбергс ссылка правильно.Использование запятой генерирует лучший код луча, чем использование andalso.Я скомпилировал следующий код, используя флаг + to_asm:

a(A,B) ->
    case ok of
        _ when A, B -> true;
        _ -> false
    end.
aa(A,B) ->
    case ok of
        _ when A andalso B -> true;
        _ -> false
    end.

, который генерирует

{function, a, 2, 2}.
  {label,1}.
    {func_info,{atom,andAndAndalso},{atom,a},2}.
  {label,2}.
    {test,is_eq_exact,{f,3},[{x,0},{atom,true}]}.
    {test,is_eq_exact,{f,3},[{x,1},{atom,true}]}.
    {move,{atom,true},{x,0}}.
    return.
  {label,3}.
    {move,{atom,false},{x,0}}.
    return.

{function, aa, 2, 5}.
  {label,4}.
    {func_info,{atom,andAndAndalso},{atom,aa},2}.
  {label,5}.
    {test,is_atom,{f,7},[{x,0}]}.
    {select_val,{x,0},{f,7},{list,[{atom,true},{f,6},{atom,false},{f,9}]}}.
  {label,6}.
    {move,{x,1},{x,2}}.
    {jump,{f,8}}.
  {label,7}.
    {move,{x,0},{x,2}}.
  {label,8}.
    {test,is_eq_exact,{f,9},[{x,2},{atom,true}]}.
    {move,{atom,true},{x,0}}.
    return.
  {label,9}.
    {move,{atom,false},{x,0}}.
    return.

Я смотрел только на то, что генерируется с флагом + to_core, но очевидно, что есть оптимизацияшаг между to_core и to_asm.

4 голосов
/ 21 мая 2011

Логические операторы « и » и « или » всегда оценивают аргументы с обеих сторон оператора.Принимая во внимание, что если вы хотите функциональность операторов C && и || (где 2-й аргумент оценивается только при необходимости ... например, если мы хотим оценить "true orelse *"1010 * false ", как только будет установлено, что истина является первым аргументом, второй аргумент не будет оцениваться, что не относится к случаю, если использовалось" или"), перейти к" andalal"и" orelse".

4 голосов
/ 17 мая 2011

Это историческая причина.and был реализован до andalso, который был представлен в Erlang 5.1 (единственная ссылка, которую я сейчас могу найти, это EEP-17 ).Защита не была изменена из-за обратной совместимости.

...