Изменения

м
Загрузка 2820-prealloc.wiki
<!-- R:Оптимизация/Предварительное выделение памяти -->
 
 
 
{{CC-BY-4.0|author=автором Артём Клевцов}}
{{Pkg-req-notice}}
 
== Предварительное выделение памяти ==
Частой задачей, решаемой с помощью циклов, является выполнение расчётов и занесение результатов в переменную. Таким образом, результирующая переменная будет заполняться данными по мере работы цикла. Предварительное выделение памяти (preallocate) позволяет ускорить работу циклов, работающих с постепенной заполняемыми данными. Суть данного метода заключается в том, чтобы заранее выделить место в оперативной памяти, в которую будут записываться данные во время работы цикла. Выделение памяти осуществляется путём указания типа и размера переменной. Если этого не сделать, то при каждой новой итерации необходимо выделять новое место в памяти и производить туда запись.
Обратите внимание, что переменные, участвующие в цикле, должны быть объявлены до того, как будут использоваться.
{{r-code|code=<nowiki>> noaaloc <- function(n) {+ x <- NULL # объявляем пустую переменную+ for (i in seq_len(n))+ x[i] <- i * i+ x+ }> > alloc <- function(n) {+ x <- integer(n) # объявляем переменную нужного типа и размера+ for (i in seq_len(n))+ x[i] <- i * i+ x+ }> microbenchmark(noaaloc(10^4), alloc(10^4))Unit: milliseconds expr min lq median uq max neval noaaloc(10^4) 41.746 42.719 43.353 44.603 76.31 100 alloc(10^4) 5.524 5.896 6.019 6.777 27.35 100</nowiki>}}
=== Создание объектов в R ===alloc <- function(n) { x <- integer(n) # объявляем переменную нужного типа и размера for (i in seq_len(n)) x[i] <- i * i x}</nowiki>}}
Теперь срвним время выполнения объявленных функций: {{r-code|code=<nowiki>microbenchmark(noaaloc(10^4), alloc(10^4))#> Unit: milliseconds#> expr min lq median uq max neval#> noaaloc(10^4) 38.545 39.596 39.977 40.595 78.476 100#> alloc(10^4) 5.546 5.843 6.112 6.443 7.593 100</nowiki>}} ==Создание пустых объектов в R = Векторы === Векторы ===
{| class="prettytable wide"
Создание любого типа вектора можно также осуществить с помощью функции <code>vector()</code>. Данная функция принимает два аргумента: <code>mode</code>, указывающая тип данных и <code>length</code>, указывающая длину вектора. Например, создание вектора целых чисел, длиной 100 можно создать с помощью следующих команд:
{{r-code|code=<nowiki>> x <- integer(100)> x <- vector("integer", 100)</nowiki>}}
==== Списки ====
Списки можно создавать с помощью уже рассмотренной ранее функции <code>vector()</code>:
{{r-code|code=<nowiki>l <- vector("list", 10)</nowiki>}}
==== Матрицы ====
Матрицы создаются с помощью соответствующей функции <code>matrix()</code>. Для создания матрицы необходимой размера, нам нужно указать количество строк и столбцов. Пример создания матрицы:
{{r-code|code=<nowiki>> m <- matrix(NA, nrow = 100, ncol = 10)</nowiki>}}
Поскольку матрица является также массивом, то матрицу можно также создать с помощью функции <code>array()</code>. Например:
{{r-code|code=<nowiki>> m <- array(NA, dim = c(100, 10))</nowiki>}}
Переменные, полученные с помощью функций <code>matrix()</code> и <code>array()</code> будут идентичными. Убедиться в этом можно с помощью функции <code>identical()</code>:
{{r-code|code=<nowiki>> identical(matrix(NA, nrow = 100, ncol = 10),+ array(NA, dim = c(100, 10)))#> [1] TRUE</nowiki>}}
Матрицы и массивы можно также получить путём преобразования векторов или списков. Для этого необходимо изменить атрибут объекта, в котом хранится информация о размерности объекта. Получиться информацию о размерности объекта можно с помощью функции <code>dim()</code>. Данная функция также позволяет изменять размерность объекта. Приведём примеры:
{{r-code|code=<nowiki>> m <- array(NA, dim = c(3, 2)) # создаём двухмерный массив с 3 строками и 2 столбцами> m#> [,1] [,2]#> [1,] NA NA#> [2,] NA NA#> [3,] NA NA> dim(m)#> [1] 3 2> dim(m) <- c(2, 3) # изменяем количество строк и столбцов> m#> [,1] [,2] [,3]#> [1,] NA NA NA#> [2,] NA NA NAdim(m)#> [1] 2 3</nowiki>}} Теперь мы может преобразовать вектор в матрицы путём присвоения вектору нужной нам размерности: {{r-code|code=<nowiki>m <- rep(NA, 1000)dim(m) <- c(100, 10)</nowiki>}} Обратим внимание на то, что количество элементов в векторе и массиве должно быть одинаковым, в противном случае R выдаст ошибку. Результат данного преобразования будут также идентичен предыдущим примерам: {{r-code|code=<nowiki>m1 <- matrix(NA, nrow = 100, ncol = 10)m2 <- rep(NA, 1000)dim(m2) <- c(100, 10)identical(m1, m2)#> [1] TRUE</nowiki>}} === Таблицы данных === Таблицы данных (<code>data.frame</code>) могут могу быть созданы путём объединения векторов, содержащих требуемые типы данных (см. [[{{FULLPAGENAME}}#Векторы| выше о создании векторов]]): {{r-code|code=<nowiki>d <- data.frame(A = integer(100), B = character(100), C = double(100), D = double(100), E = integer(100), stringsAsFactors = FALSE)</nowiki>}}
== Примечания ==