Last active
July 12, 2020 01:29
-
-
Save genkuroki/969c4ac8f518e343f44bd6e8d771a94a to your computer and use it in GitHub Desktop.
追加メモリ消費がない演算
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# メモリ割当がない演算\n\n黒木玄\n\n2020-07-05, 2020-07-12" | |
}, | |
{ | |
"metadata": { | |
"toc": true | |
}, | |
"cell_type": "markdown", | |
"source": "<h1>目次<span class=\"tocSkip\"></span></h1>\n<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#in-place計算ではメモリ割当は生じない\" data-toc-modified-id=\"in-place計算ではメモリ割当は生じない-1\"><span class=\"toc-item-num\">1 </span>in-place計算ではメモリ割当は生じない</a></span></li><li><span><a href=\"#dot-付きの-=-による代入ではメモリ割当が生じない\" data-toc-modified-id=\"dot-付きの-=-による代入ではメモリ割当が生じない-2\"><span class=\"toc-item-num\">2 </span>dot 付きの = による代入ではメモリ割当が生じない</a></span></li><li><span><a href=\"#viewによる部分配列のメモリ割当は生じない\" data-toc-modified-id=\"viewによる部分配列のメモリ割当は生じない-3\"><span class=\"toc-item-num\">3 </span>viewによる部分配列のメモリ割当は生じない</a></span></li><li><span><a href=\"#sum(f(x)-for-x-in-A)-ではメモリ割当はほぼ生じない\" data-toc-modified-id=\"sum(f(x)-for-x-in-A)-ではメモリ割当はほぼ生じない-4\"><span class=\"toc-item-num\">4 </span>sum(f(x) for x in A) ではメモリ割当はほぼ生じない</a></span></li></ul></div>" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "VERSION", | |
"execution_count": 1, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 1, | |
"data": { | |
"text/plain": "v\"1.5.0-rc1.0\"" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "using BenchmarkTools\nusing LinearAlgebra", | |
"execution_count": 2, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## in-place計算ではメモリ割当は生じない\n\nhttps://docs.julialang.org/en/v1/stdlib/LinearAlgebra/#Low-level-matrix-operations-1" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "n = 1024\n\n@time A = randn(n, n)\n@time B = randn(n, n)\n@time C = randn(n, n);", | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 0.080893 seconds (144.67 k allocations: 15.690 MiB, 10.62% gc time)\n 0.005487 seconds (2 allocations: 8.000 MiB)\n 0.005638 seconds (2 allocations: 8.000 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "n^2*8/1024^2", | |
"execution_count": 4, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 4, | |
"data": { | |
"text/plain": "8.0" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime A*B;", | |
"execution_count": 5, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 30.124 ms (2 allocations: 8.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `A*B` では `A*B` の分の8MBのメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime A*B*C;", | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 66.953 ms (4 allocations: 16.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `A*B*C` では `Tmp = A*B` と `Tmp*C` の分の16MBのメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime A^2*B*C;", | |
"execution_count": 7, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 104.131 ms (6 allocations: 24.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime A^15*B*C;", | |
"execution_count": 8, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 286.271 ms (16 allocations: 64.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように行列の冪乗でもメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "Y = similar(A)\n@btime mul!(Y, A, B)\nY == A*B", | |
"execution_count": 9, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 22.128 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 9, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のようにin-place計算すればメモリ割当が生じない." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime X = 2A;", | |
"execution_count": 10, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 2.976 ms (2 allocations: 8.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように行列のスカラー倍でもメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "Y = copy(A)\n@btime lmul!(2, Y)\nY == 2A", | |
"execution_count": 11, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 433.408 μs (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 11, | |
"data": { | |
"text/plain": "false" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように行列のスカラー倍もin-place計算にすればメモリ割当が生じない." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## dot 付きの = による代入ではメモリ割当が生じない\n\nhttps://docs.julialang.org/en/v1/manual/performance-tips/#More-dots:-Fuse-vectorized-operations-1" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sindot(A) = sin.(A)", | |
"execution_count": 12, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 12, | |
"data": { | |
"text/plain": "sindot (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime X = sindot(A)\nX = sindot(A);", | |
"execution_count": 13, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 15.778 ms (2 allocations: 8.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `X = sindot(A)` では `sin.(A)` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sindots!(Y, A) = Y .= sin.(A)", | |
"execution_count": 14, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 14, | |
"data": { | |
"text/plain": "sindots! (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime sindots!(Y, A)\nsindots!(Y, A)\nY == X", | |
"execution_count": 15, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 13.371 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 15, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のようにin-place計算するようにすればメモリ割当は生じない." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sinatdot!(Y, A) = @.(Y = sin(A))", | |
"execution_count": 16, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 16, | |
"data": { | |
"text/plain": "sinatdot! (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime sinatdot!(Y, A)\nsinatdot!(Y, A)\nY == X", | |
"execution_count": 17, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 13.170 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 17, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `@.` マクロでまとめてdotsを付けてもメモリ割当は生じなくなる." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## viewによる部分配列のメモリ割当は生じない\n\nhttps://docs.julialang.org/en/v1/manual/performance-tips/#Consider-using-views-for-slices-1" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "cutboundary(A) = A[2:end-1, 2:end-1]", | |
"execution_count": 18, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 18, | |
"data": { | |
"text/plain": "cutboundary (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime X = cutboundary(A)\nX = cutboundary(A);", | |
"execution_count": 19, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 2.850 ms (2 allocations: 7.97 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `X = cutboundary(A)` では `A[2:end-1, 2:end-1]` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "cutboundary!(Y, A) = @. @views Y = A[2:end-1, 2:end-1]", | |
"execution_count": 20, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 20, | |
"data": { | |
"text/plain": "cutboundary! (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "Y = Array{eltype(A), 2}(undef, size(A) .- (2, 2))\n@btime cutboundary!(Y, A)\ncutboundary!(Y, A)\nX == Y", | |
"execution_count": 21, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 1.958 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 21, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のようにin-place計算にすればメモリ割当は生じない." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "mulinteriors(A, B) = A[2:end-1, 2:end-1]*B[2:end-1, 2:end-1]", | |
"execution_count": 22, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 22, | |
"data": { | |
"text/plain": "mulinteriors (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "X = mulinteriors(A, B)\n@btime X = mulinteriors(A, B);", | |
"execution_count": 23, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 38.730 ms (6 allocations: 23.91 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `X = mulinteriors(A, B)` では `A[2:end-1, 2:end-1]` と `B[2:end-1, 2:end-1]` と `A[2:end-1, 2:end-1]*B[2:end-1, 2:end-1]` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "mulinteriors!(Y, A, B) = @views mul!(Y, A[2:end-1, 2:end-1], B[2:end-1, 2:end-1])", | |
"execution_count": 24, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 24, | |
"data": { | |
"text/plain": "mulinteriors! (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "Y = Array{eltype(A), 2}(undef, size(A) .- (2, 2))\n@btime mulinteriors!(Y, A, B)\nmulinteriors!(Y, A, B)\nX == Y", | |
"execution_count": 25, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 24.934 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 25, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のようにin-place計算にすればメモリ割当は生じない." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "x = y =range(-1, 1, length=n)\nu = @. x^2 + (y')^2;", | |
"execution_count": 26, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "function Δ_for(u)\n m, n = size(u)\n v = Array{eltype(u), 2}(undef, m-2, n-2)\n for j in 2:n-1, i in 2:m-1\n v[i-1, j-1] = (\n u[i-1, j] +\n u[i+1, j] +\n u[i, j-1] +\n u[i, j+1] - 4u[i, j]\n )\n end\n v\nend", | |
"execution_count": 27, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 27, | |
"data": { | |
"text/plain": "Δ_for (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime z = Δ_for(u)\nz = Δ_for(u)\nextrema(z)", | |
"execution_count": 28, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 4.788 ms (2 allocations: 7.97 MiB)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 28, | |
"data": { | |
"text/plain": "(1.5288635095700442e-5, 1.5288635099253156e-5)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `z = Δ_for(u)` では `Δ_for(u)` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "function Δ_dotsviews(u)\n @. @views (\n u[1:end-2, 2:end-1] +\n u[3:end, 2:end-1] +\n u[2:end-1, 1:end-2] +\n u[2:end-1, 3:end ] - 4u[2:end-1, 2:end-1]\n )\nend", | |
"execution_count": 29, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 29, | |
"data": { | |
"text/plain": "Δ_dotsviews (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime v = Δ_dotsviews(u)\nv = Δ_dotsviews(u)\nv == z", | |
"execution_count": 30, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 5.014 ms (2 allocations: 7.97 MiB)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 30, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `v = Δ_dotsviews(u)` でも `Δ_dotsviews(u)` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "function Δ!(w, u)\n @. @views w = (\n u[1:end-2, 2:end-1] +\n u[3:end, 2:end-1] +\n u[2:end-1, 1:end-2] +\n u[2:end-1, 3:end ] - 4u[2:end-1, 2:end-1]\n )\nend", | |
"execution_count": 31, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 31, | |
"data": { | |
"text/plain": "Δ! (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "w = Array{eltype(u), 2}(undef, n-2, n-2)\n@btime Δ!(w, u)\nΔ!(w, u)\nw == v", | |
"execution_count": 32, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 3.061 ms (0 allocations: 0 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 32, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のようにin-place計算にすればメモリ割当が生じない." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## sum(f(x) for x in A) ではメモリ割当はほぼ生じない\n\nhttps://docs.julialang.org/en/v1/manual/arrays/#Generator-Expressions-1" | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sumsindot(A) = sum(sin.(A))", | |
"execution_count": 33, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 33, | |
"data": { | |
"text/plain": "sumsindot (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime x = sumsindot(A)", | |
"execution_count": 34, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 16.134 ms (3 allocations: 8.00 MiB)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 34, | |
"data": { | |
"text/plain": "-1239.293008526668" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `sum(sin.(A))` では `sin.(A)` の分だけメモリ割当が生じる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "sumsinfor(A) = sum(sin(a) for a in A)", | |
"execution_count": 35, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 35, | |
"data": { | |
"text/plain": "sumsinfor (generic function with 1 method)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime y = sumsinfor(A)", | |
"execution_count": 36, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 12.885 ms (1 allocation: 16 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 36, | |
"data": { | |
"text/plain": "-1239.2930085267185" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように `sum(sin(a) for a in A)` ではメモリ割当がほぼ生じない." | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "以下は配列 `[sin(a) for a in A]` とGenerator `(sin(a) for a in A)` の違いの確認." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "T = sin.(A)\ntypeof(T), size(T)", | |
"execution_count": 37, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 37, | |
"data": { | |
"text/plain": "(Array{Float64,2}, (1024, 1024))" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "S = [sin(a) for a in A]\ntypeof(S), size(S)", | |
"execution_count": 38, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 38, | |
"data": { | |
"text/plain": "(Array{Float64,2}, (1024, 1024))" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "G = (sin(a) for a in A)\ntypeof(G), size(G)", | |
"execution_count": 39, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 39, | |
"data": { | |
"text/plain": "(Base.Generator{Array{Float64,2},typeof(sin)}, (1024, 1024))" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "collect(G) == S == T", | |
"execution_count": 40, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 40, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime S = [sin(a) for a in A];", | |
"execution_count": 41, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 15.228 ms (3 allocations: 8.00 MiB)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime G = (sin(a) for a in A);", | |
"execution_count": 42, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 74.179 ns (1 allocation: 16 bytes)\n", | |
"name": "stdout" | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "上のように, 配列 `S = [sin(a) for a in A]` と違って, Generator `G = (sin(a) for a in A)` の作成にほとんど時間はかからない. Generatorの作成時に `sin(a)` 達は計算されていない." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime sum(S)", | |
"execution_count": 43, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 302.780 μs (1 allocation: 16 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 43, | |
"data": { | |
"text/plain": "-1239.293008526668" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@btime sum(G)", | |
"execution_count": 44, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": " 12.906 ms (1 allocation: 16 bytes)\n", | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "execute_result", | |
"execution_count": 44, | |
"data": { | |
"text/plain": "-1239.2930085267185" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "markdown", | |
"source": "上のように, Generatorの和では和の計算時に `sin(a)` が計算されるのでその分だけ時間がかかる." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"@webio": { | |
"lastKernelId": null, | |
"lastCommId": null | |
}, | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/969c4ac8f518e343f44bd6e8d771a94a" | |
}, | |
"gist": { | |
"id": "969c4ac8f518e343f44bd6e8d771a94a", | |
"data": { | |
"description": "追加メモリ消費がない演算", | |
"public": true | |
} | |
}, | |
"kernelspec": { | |
"name": "julia-1.5", | |
"display_name": "Julia 1.5.0-rc1", | |
"language": "julia" | |
}, | |
"language_info": { | |
"file_extension": ".jl", | |
"name": "julia", | |
"mimetype": "application/julia", | |
"version": "1.5.0" | |
}, | |
"toc": { | |
"nav_menu": {}, | |
"number_sections": true, | |
"sideBar": true, | |
"skip_h1_title": true, | |
"base_numbering": 1, | |
"title_cell": "目次", | |
"title_sidebar": "Contents", | |
"toc_cell": true, | |
"toc_position": {}, | |
"toc_section_display": true, | |
"toc_window_display": false | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment