если оптимизация условия оператора

У меня была та же проблема, но я искал решение, которое работает с трубой (%>%). Использование tidyr::spread и tidyr::gather из tidyverse делает трюк. Я использую те же данные, что и @Brian Diggs, но с именами переменных верхнего регистра, которые не имеют двойных имен переменных при преобразовании в wide:

library(tidyverse)

dat <- data.frame(A = rep(LETTERS[1:3], 3),
                  B = rep(letters[1:3], each = 3),
                  V = 1:9)[-2, ]
dat %>% 
  spread(key = B, value = V, fill = NA) %>% # turn data to wide, using fill = NA to generate missing values
  gather(key = B, value = V, -A) %>% # go back to long, with the missings
  ggplot(aes(x = A, y = V, fill = B)) +
  geom_col(position = position_dodge())

Edit:

еще более простое решение этой проблемы в сочетании с трубой. Использовать tidyr::complete дает тот же результат в одной строке:

dat %>% 
  complete(A, B) %>% 
  ggplot(aes(x = A, y = V, fill = B)) +
  geom_col(position = position_dodge())
5
задан Ijas Ameenudeen 18 January 2019 в 11:04
поделиться

11 ответов

Для C оптимизированы C++, C#, Java и другие булевы выражения языков.NET так, чтобы, как только достаточно известно, ничто иное не было оценено.

Старый прием для того, чтобы сделать запутываемый код должен был использовать это, чтобы создать если операторы, такие как:

a || b();

если "a" верен, "b ()" никогда не оценивался бы, таким образом, мы можем переписать его в:

if(!a)
    b();

и так же:

a && b();

стал бы

if(a)
    b();

Обратите внимание на то, что это только допустимо для || и && оператор. Эти два оператора | и и являются побитовыми или, и и, соответственно, и поэтому не "оптимизированы".

Править: Как упомянуто другими, пытаясь оптимизировать код с помощью логики короткого замыкания очень редко хорошо проведенное время.

Сначала пойдите для ясности, и потому что легче читать и понять. Кроме того, при попытке быть слишком умным простым переупорядочением условий, мог бы привести к дико другому поведению без любой очевидной причины.

Во-вторых, пойдите для оптимизации, но только после синхронизации и профилирования. Слишком многие разработчик делают преждевременную оптимизацию без профилирования. Большую часть времени это абсолютно бесполезно.

9
ответ дан 18 December 2019 в 07:12
поделиться

В соответствии с этой статьей PHP действительно срывает оценку, что означает, что, если первое условие соблюдают, второе даже не оценено. Довольно легко протестировать также (от статьи):

<?php
/* ch06ex07 – shows no output because of short circuit evaluation */

if (true || $intVal = 5) // short circuits after true
{

echo $intVal; // will be empty because the assignment never took place
}

?>
2
ответ дан 18 December 2019 в 07:12
поделиться

В значительной степени каждый язык делает оценку короткого замыкания. Значение второго условия только оценено, если это aboslutely необходимый для. Чтобы это работало, большинство языков использует двойной канал, ||, не единственный, |.

См. http://en.wikipedia.org/wiki/Short-circuit_evaluation

3
ответ дан 18 December 2019 в 07:12
поделиться

В C, C++ и Java, операторе:

if (condition1 | condition2) {
  ...
}

оценит оба условия каждый раз и только будет верен, если все выражение будет верно.

Оператор:


if (condition1 || condition2) {
  ...
}

оценит condition2 только если condition1 ложь. Разница является значительной, если condition2 является функцией или другим выражением с побочным эффектом.

Нет, однако, никакого различия между || случай и if/else случай.

3
ответ дан 18 December 2019 в 07:12
поделиться

Замыкание накоротко не для оптимизации. Это - основная цель, должен избежать кода вызова, который не будет работать, все же приводить к читаемому тесту. Пример:

if (i < array.size() && array[i]==foo) ...

Обратите внимание, что выстраивают [я] могу получить нарушение прав доступа, если я вне диапазона, и разрушьте программу. Таким образом эта программа, конечно, в зависимости от замыкания накоротко оценки!

Я полагаю, что это - причина записи выражений этого пути намного чаще, чем проблемы оптимизации.

2
ответ дан 18 December 2019 в 07:12
поделиться

Я видел много этих типов вопросов в последнее время - оптимизация до энного градуса.

Я думаю, что это имеет смысл при определенных обстоятельствах:

  1. Вычислительное условие 2 не является постоянной операцией времени
  2. Вы просите строго образовательные цели - Вы хотите знать, как язык работает, для не сохранения 3us.

В других случаях, вызывающих беспокойство о "самом быстром" способе выполнить итерации или проверить условное выражение, глупо. Вместо того, чтобы писать тесты, которые требуют, чтобы миллионы пробных версий видели любого записываемого (но незначительный) различие, внимание на ясность.

Когда кто-то еще (могли быть Вы!) забирает этот код за месяц или год, что будет самым важным, ясность.

В этом случае Ваш первый пример короче, более ясен и не требует, чтобы Вы повторили себя.

2
ответ дан 18 December 2019 в 07:12
поделиться

В то время как использование закорачивающий в целях оптимизации часто является излишеством, существуют, конечно, другие неопровержимые доводы для использования его. Один такой пример (в C++) следующий:

if( pObj != NULL && *pObj == "username" ) {
    // Do something...
}

Здесь, на замыкание накоротко полагаются для обеспечения этого pObj был выделен до разыменования его. Это намного более кратко, чем то, что вложило if операторы.

1
ответ дан 18 December 2019 в 07:12
поделиться

| побитовый оператор в PHP. Это не означает $a OR $b, точно. Вы захотите использовать двойной канал. И да, как упомянуто, PHP действительно закорачивает оценку. Точно так же, если первое условие && пункт оценивает ко лжи, PHP не оценивает остальную часть пункта, также.

0
ответ дан 18 December 2019 в 07:12
поделиться

Так как это - отмеченный агностик языка, в которого я вмешаюсь. Для Perl, по крайней мере, первая опция достаточна, я не знаком с PHP. Это оценивает слева направо и выбывает, как только условие соблюдают.

0
ответ дан 18 December 2019 в 07:12
поделиться

На большинстве языков с достойной оптимизацией первый будет работать просто великолепно.

0
ответ дан 18 December 2019 в 07:12
поделиться

VB.net имеет два замечательных выражения под названием "OrElse" и "AndAlso"

OrElse сорвет себя в первый раз, когда он достигает Истинной оценки, и выполните код, которого Вы требуете.

If FirstName = "Luke" OrElse FirstName = "Darth" Then
   Console.Writeline "Greetings Exalted One!"
End If

AndAlso сорвет себя в первый раз это Ложная оценка и не оценит код в блоке.

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
   Console.Writeline "You are the one and only."
End If

Я нахожу оба из них полезными.

0
ответ дан 18 December 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: