Лучше, если заявления с несколькими условиями или больше, если заявления? - PullRequest
0 голосов
/ 09 октября 2018

Я математик, поэтому я не очень разбираюсь в IT.И я хочу знать, быстрее ли использовать операторы с несколькими условиями или больше, если / иначе, если операторы, как в примере ниже.Представьте, что у меня действительно большая таблица данных (с миллионами строк) и эта функция if в функции, которую я применяю к каждой строке одного столбца, а результат сохраняется в новом столбце.И я просто хочу выяснить, есть ли какая-то разница (быстрее / медленнее / одинакова) между этими двумя подходами.

    if (is.na(numerator) == TRUE){
        result = 0
    }  else if (numerator == 0){
        result = 0
    }  else if (is.na(denominator) == TRUE){
        result = max
    }  else if (denominator == 0){
        result = max
    }  else {
        result = numerator/denominator
    }

ИЛИ

    if (is.na(numerator) == TRUE || numerator == 0){
        result = 0
    }  else if (is.na(denominator) == TRUE || denominator == 0){
        result = max
    }  else {
        result = numerator/denominator
    }

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Давайте проведем простой эксперимент!

Фиктивные данные

data <- data.frame(numerator = sample(c(0:9, NA), 10000, replace = T),
                   denominator = sample(c(0:9, NA), 10000, replace = T))

Две функции, состоящие из двух условий "если"

f1 <- function(x){
  num <- x[1] ; denom <- x[2]
  if (is.na(num)){
    result = 0
  }  else if (num == 0){
    result = 0
  }  else if (is.na(denom)){
    result = Inf
  }  else if (denom == 0){
    result = Inf
  }  else {
    result = num / denom
  }
  return(result)
}

f2 <- function(x){
  num <- x[1] ; denom <- x[2]
  if (is.na(num) || num == 0){
    result = 0
  }  else if (is.na(denom) || denom == 0){
    result = Inf
  }  else {
    result = num / denom
  }
  return(result)
}

Сравнительный анализ

library(microbenchmark)
library(ggplot2)

res <- microbenchmark(
  type1 = {
    quotient1 <- apply(data, 1, f1)
  }, type2 = {
    quotient2 <- apply(data, 1, f2)
  }, times = 100
)

res
# Unit: milliseconds
#  expr      min       lq     mean   median       uq       max
# type1 21.91925 23.70445 27.16314 25.52339 26.90110 122.91710
# type2 22.00139 23.64297 26.11080 25.04576 26.46136  42.62506

autoplot(res)

enter image description here

Заключение

Вы можете несколько раз попробовать эталонный тест и обнаружить, что между двумя if нет существенной разницыусловия.

0 голосов
/ 09 октября 2018

Hy,

, чтобы улучшить приведенную выше форму кода. Я бы посоветовал вам принять сначала оператор if, который произойдет чаще всего.Это немного ускорит код, потому что в большинстве случаев область if else не проверяется до конца.Я провел очень маленький тест по этому вопросу:

df <- data.frame(check = sample(c(0,1),size = 10000, replace = T, prob = c(0.1,0.9)),
                 solution = rep(NA, 10000))

start_t <- Sys.time()
for (idx in seq_len(nrow(df))) {
  if(df[idx, "check"]==0) {
    df[idx, "solution"] <- "zero"
  } else if (df[idx, "check"]==1) {
    df[idx, "solution"] <- "one"
  }
}
print(Sys.time()-start_t)

Этот код необходим в моей системе Time difference of 0.7524531 secs.Вы можете видеть, что в кадре данных будет больше единиц, чем нулей.Следовательно, я переключу проверяющие операторы и установлю «if check == 1» в начале.

df <- data.frame(check = sample(c(0,1),size = 10000, replace = T, prob = c(0.1,0.9)),
                 solution = rep(NA, 10000))

start_t <- Sys.time()
for (idx in seq_len(nrow(df))) {
  if(df[idx, "check"]==1) {
    df[idx, "solution"] <- "one"
  } else if (df[idx, "check"]==0) {
    df[idx, "solution"] <- "zero"
  }
}
print(Sys.time()-start_t)

Для этого кода требуется только Time difference of 0.6977119 secs.Это на ~ 8% быстрее и выполняет ту же работу, что и приведенный выше пример.Надеюсь, вы поняли мою точку зрения и удачи с вашим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...