Комментарии 9
Спасибо за статью! Бывает непросто перестать мыслить циклами :)
Было бы интересно увидеть список задач, где без циклов не обойтись. Например, у меня такой кейс: есть вектор с названиями файлов формата json, нужно последовательно их считывать, далее в каждом файле считывать несколько подсписков (для каждого файла кол-во подсписков разное). Сейчас это реализовано двумя циклами for: внешний для считывания файлов и внутренний для прохода по всем подспискам. Можно ли это реализовать более эффективно без циклов?
Было бы интересно увидеть список задач, где без циклов не обойтись. Например, у меня такой кейс: есть вектор с названиями файлов формата json, нужно последовательно их считывать, далее в каждом файле считывать несколько подсписков (для каждого файла кол-во подсписков разное). Сейчас это реализовано двумя циклами for: внешний для считывания файлов и внутренний для прохода по всем подспискам. Можно ли это реализовать более эффективно без циклов?
+1
На моем ноутбуке расчеты занимают 39 секунд, хотя того же результата можно достичь за 0,009 секундыС точки зрения человека, далекого от R, это очень странная ситуация. Обработка массива данных всегда где-то под капотом сводится к циклу. Получается, что стандартная реализация цикла средствами языка несет столько накладных расходов, что выполняется в 4 тысячи раз медленнее «железного» цикла?
По-моему, эта проблема должна решаться оптимизациями на стороне компилятора — разворачивание циклов, SIMD и другие хитрости, как это делает, например, компилятор C. А добавлением целого семейства специализированных функций выглядит, как костыль.
0
Больше похоже на ленивое выполнение, когда в таблицу внесли запись вида «отдавать дополнительную колонку, в которой находится результат операции». А так как после этого данные никто и не читает, то реальной работы и не происходит.
0
Нет, просто во втором случае все работает параллельно. И R сам по себе на эту параллельность заточен. Вполне возможно что обычный цикл даже толком не оптимизирован — он не используется для больших данных. Но последнее — это уже домыслы.
0
for(row in 1:nrow(testDF))
testDF[row, 3] < — testDF[row, 1] + testDF[row, 2] # Ужас!
Согласен. «Ужас!». Но ведь — не «Ужас-ужас!»
Попробуйте «штатное» (т.е. без всяких библиотек) для R:
system.time(testDF$c<-testDF$a+testDF$b)
Будете приятно удивлены.
0
А про самый современный подход ничего не сказано. Функциональный подход на базе purrr. Интересующимся можно взглянуть для затравки на доклад с rstudio::conf 2017, почитать книгу R4DS, раздел "Итераторы". А еще есть более хитрые циклы, когда надо, например, применять функции с условием для определенных строк выбранных столбцов дата фрейма… А еще неплохо бы знать структуры данных и специфику используемых пакетов. Например, как быстро провести обработку data.frame с POSIXct с разными time-zone? Любой цикл "в лоб" даст безумное по исполнению время.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Разработка на R: тайны циклов