Penyiaran terpadu di Julia: semua yang perlu Anda ketahui untuk menghindari jebakan – Beragampengetahuan
Oleh: Blog Bogumił Kamiński
Repost dari:
Penyiaran adalah fitur hebat Julia dan dengan cepat menjadi alat pilihan
oleh pengembang karena nyaman digunakan.
Namun, dalam situasi yang lebih kompleks, ini bisa menjadi rumit. Masalahnya karena
Siarannya yang kuat memiliki desain yang rumit dan bahkan Panduan Pengguna Julia mencakup empat
Bagian yang berbeda untuk membahas berbagai aspek fungsionalitas:
di sini, di sini, di sini, dan di sini.
Untuk itu, beberapa waktu yang lalu saya menulis postingan tentang @. TIBA
memperjelas penggunaannya. Sebuah diskusi baru-baru ini tentang Julia Discourse mendorong saya untuk menulis
Posting lain tentang topik ini.
Hari ini saya akan membahas dua hal yang berkaitan dengan penggabungan siaran:
wadah siaran dari berbagai bentuk
dan aliasing dalam tugas siaran.
Contoh yang disajikan telah diuji di bawah Julia 1.9.0-rc1.
Mari saya mulai dengan sebuah contoh:
julia> x = string.([1, 2, 3], ",", ["a" "b"], ":")
3×2 Matrix{String}:
"1,a:" "1,b:"
"2,a:" "2,b:"
"3,a:" "3,b:"
julia> y = rand.(Int8, 1:3)
3-element Vector{Vector{Int8}}:
[-95]
[65, -119]
[-77, -78, -5]
julia> string.(x, y)
3×2 Matrix{String}:
"1,a:Int8[-95]" "1,b:Int8[-95]"
"2,a:Int8[65, -119]" "2,b:Int8[65, -119]"
"3,a:Int8[-77, -78, -5]" "3,b:Int8[-77, -78, -5]"
julia> string.([1, 2, 3], ",", ["a" "b"], ":", rand.(Int8, 1:3))
3×2 Matrix{String}:
"1,a:Int8[-127]" "1,b:Int8[-93]"
"2,a:Int8[92, -91]" "2,b:Int8[-88, 118]"
"3,a:Int8[-104, -29, -38]" "3,b:Int8[23, 109, 76]"
Yang bisa kita lihat di sini adalah x = string.([1, 2, 3], ",", ["a" "b"], ":") operasi menghasilkan matriks 3×2,
ketika y = rand.(Int8, 1:3) menciptakan vektor 3-elemen. Karena di Julia vektor diperlakukan sebagai kolom
matriks dan vektor memiliki ukuran yang sesuai dan dapat digunakan dalam penyiaran.
Panggilan string.(x, y) menggunakan kembali elemen dari y di setiap baris. Hasilnya adalah akhiran dari setiap string
dalam matriks yang dihasilkan sama untuk setiap baris.
Oleh karena itu, Anda mungkin terkejut menggabungkan ekspresi menjadi satu panggilanstring.([1, 2, 3], ",", ["a" "b"], ":", rand.(Int8, 1:3)) anda mendapatkan hasil yang berbeda.
Sekarang setiap akhiran berbeda (saya menggunakan angka acak untuk menunjukkan kepada Anda bahwa akhiran memang berbeda).
Apa alasan perilaku ini? Seperti yang dijelaskan dalam entri Panduan Pengguna Julia yang saya tautkan di pendahuluan
Julia melakukan penggabungan siaran. Ini berarti berperilaku seolah-olah itu membuat satu putaran lebih dari dua
ukuran matriks keluaran dan mengevaluasi ekspresi:string(p, ",", q, ":", rand.(Int8, r)) untuk nilai-nilai p, q Dan r menentukan cocok
dari sumber data [1, 2, 3], ["a" "b"]Dan 1:3 jangan menyimpannya saat melakukan ekspansi
Nanti 1:3 vektor pada dimensi kedua. Ini berarti kita mendapatkan sufiks yang berbeda di setiap sel.
Terkadang itu sangat diinginkan, dalam kasus lain bisa mengejutkan dan tidak diinginkan.
Pertama, izinkan saya menjelaskan cara mengatasi masalah ini. Anda dapat gunakan identity fungsi (tidak disiarkan)
untuk menghindari perilaku penggabungan siaran. Inilah cara Anda melakukannya:
julia> string.([1, 2, 3], ",", ["a" "b"], ":", identity(rand.(Int8, 1:3)))
3×2 Matrix{String}:
"1,a:Int8[45]" "1,b:Int8[45]"
"2,a:Int8[-121, 60]" "2,b:Int8[-121, 60]"
"3,a:Int8[47, -25, 42]" "3,b:Int8[47, -25, 42]"
Bagian dari ekspresi terbungkus identity dievaluasi dan kemudian dimasukkan
ekspresi siaran.
Dalam contoh kami, ini mengubah hasil operasi, karena kami menghasilkan angka acak.
Namun, meskipun hasilnya tidak terpengaruh, hal itu dapat memengaruhi kinerja secara signifikan.
Lihatlah contoh ini (waktu setelah kompilasi):
julia> @time sin.(1:1000) .+ cos.((1:1000)');
0.032546 seconds (2 allocations: 7.629 MiB)
julia> @time identity(sin.(1:1000)) .+ identity(cos.((1:1000)'));
0.005688 seconds (4 allocations: 7.645 MiB)
Apa alasan perbedaannya? Dalam kasus pertama keduanya sin Dan cos
dievaluasi 1.000.000 kali (untuk setiap sel terpisah).
Pada contoh kedua, kami hanya memiliki 1000 panggilan sin Dan cos.
Anda mungkin bertanya kapan perilaku default diinginkan? Ini sangat berguna ketika misalnya
Anda ingin menghindari aliasing. Jam tangan:
julia> m1 = tuple.([1 2], vcat.(1:3, 4:6))
3×2 Matrix{Tuple{Int64, Vector{Int64}}}:
(1, [1, 4]) (2, [1, 4])
(1, [2, 5]) (2, [2, 5])
(1, [3, 6]) (2, [3, 6])
julia> push!(m1[1, 1][2], 100)
3-element Vector{Int64}:
1
4
100
julia> m1
3×2 Matrix{Tuple{Int64, Vector{Int64}}}:
(1, [1, 4, 100]) (2, [1, 4])
(1, [2, 5]) (2, [2, 5])
(1, [3, 6]) (2, [3, 6])
julia> m2 = tuple.([1 2], identity(vcat.(1:3, 4:6)))
3×2 Matrix{Tuple{Int64, Vector{Int64}}}:
(1, [1, 4]) (2, [1, 4])
(1, [2, 5]) (2, [2, 5])
(1, [3, 6]) (2, [3, 6])
julia> push!(m2[1, 1][2], 100)
3-element Vector{Int64}:
1
4
100
julia> m2
3×2 Matrix{Tuple{Int64, Vector{Int64}}}:
(1, [1, 4, 100]) (2, [1, 4, 100])
(1, [2, 5]) (2, [2, 5])
(1, [3, 6]) (2, [3, 6])
Seperti yang Anda lihat, dalam hal ini kami biasanya menginginkannya vcat disebut secara terpisah untuk setiap sel.
Ketika kami memutuskan fusi siaran dengan identity(vcat.(1:3, 4:6)) kita mendapatkan vektor yang sama di setiap sel berturut-turut,
ini dapat menyebabkan kesalahan yang sulit ditangkap.
Pertanyaan lain adalah kapan penggabungan siaran berguna dari perspektif kinerja?
Jawabannya ada dalam panggilan sederhana seperti (waktu setelah kompilasi):
julia> @time cot.(sin.(cos.(tan.(1:10^6))));
0.057595 seconds (2 allocations: 7.629 MiB)
kami menghindari alokasi objek perantara yang tidak perlu. Kami dapat mensimulasikan kinerja non-konsolidasi
dengan injeksi identity Untuk melihat perbedaannya:
julia> @time cot.(identity(sin.(identity(cos.(identity(tan.(1:10^6)))))));
0.085532 seconds (8 allocations: 30.518 MiB)
Masalah potensial lainnya adalah aliasing dalam transfer siaran .=. Lihatlah contoh ini:
julia> x = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> x .= sum.(Ref(x))
2×2 Matrix{Int64}:
10 35
19 68
julia> x = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> x .= identity(sum.(Ref(x)))
2×2 Matrix{Int64}:
10 10
10 10
Dalam kasus pertama dari x .= sum.(Ref(x))Seperti yang telah kita diskusikan, sum.(Ref(x))
dilakukan untuk setiap sel dari x matriks. Sekarang, karena kita menggunakan .= misi siaran
kegiatan terjadi di tempat, yang berarti x Diperbarui dalam proses
dan berurutan sum.(Ref(x)) gunakan panggilan yang diubah x. Sekali lagi, hentikan siarannya
bergabung dengan identity(sum.(Ref(x))) memaksa Julia untuk mengaktualisasikan uang terlebih dahulu
lakukan latihan siaran eksternal dan kami dapatkan 10 di setiap sel.
Untuk memberikan contoh lain, mari kita lihat bagaimana kita dapat mengisi vektor yang berurutan
kekuatan 2 (tentu saja ada cara yang lebih baik untuk melakukannya):
julia> x = [1, 0, 0, 0, 0, 0, 0]
7-element Vector{Int64}:
1
0
0
0
0
0
0
julia> x .= sum.(Ref(x))
7-element Vector{Int64}:
1
1
2
4
8
16
32
Singkatnya, penting untuk dicatat bahwa Julia melakukan penggabungan siaran kapan
beroperasi pada beberapa panggilan fungsi broadcast yang saling berhubungan.
Penggabungan siaran ini umumnya meningkatkan kinerja dan mengurangi alokasi, tetapi dalam beberapa kasus
kasus yang tidak diinginkan. Situasi yang paling umum adalah:
- saat kami menyiarkan operasi pada wadah berukuran berbeda
(bila dapat menurunkan kinerja atau menyebabkan hasil yang berbeda). - saat kami membuat tugas siaran ke wadah yang juga digunakan di sisi kanan
ekspresi (ketika itu dapat menyebabkan hasil yang salah tak terduga).
Seperti yang saya tunjukkan, dalam kasus seperti itu, salah satu pemecahan masalah adalah memutuskan sambungan siaran
dengan menyertakan pemanggilan fungsi non-siaran yang memberlakukan hasil antara
perhitungan. Itu identity fungsi dapat digunakan untuk mencapai efek ini.
Terkait
Software Terbaru Saat Ini
Aplikasi yang sedang trend saat ini
object oriented programming, programming language, programming adalah, web programming, belajar programming, tournament software, software, software adalah, contoh software, apa itu software, pengertian software, aplikasi, aplikasi penghasil uang, aplikasi bokep, aplikasi video, programming
#Penyiaran #terpadu #Julia #semua #yang #perlu #Anda #ketahui #untuk #menghindari #jebakan