Chỉnh sửa: Phiên bản gốc đã sử dụng thao tác reshape
không cần thiết. Như @ DDF chỉ ra trong các ý kiến, đó là không cần thiết. Câu trả lời đã được sửa đổi kể từ đó.
Trong trường hợp phổ biến mà sao chép không phải là vấn đề, chỉ cần thực hiện real(z)
và imag(z)
(đổi tên real.(z)
và imag.(z)
trong v0.6). Tôi bao gồm điều này để giúp độc giả tương lai có vấn đề tương tự, nhưng những người có thể không quan tâm đến việc sao chép.
Như bạn đề xuất, bạn có thể thao tác các bước tiến của z
để tránh sao chép dữ liệu. Đơn giản chỉ cần
zfl = reinterpret(Float64, z)
zre = @view zfl[1:2:end-1]
zim = @view zfl[2:2:end]
Kết hợp, chúng tôi quan sát thấy không có sao chép dữ liệu (phân bổ là do chế độ xem mảng được phân bổ và tối thiểu).
julia> z = Vector{Complex128}(100000);
julia> function reimvec(z)
zfl = reinterpret(Float64, z)
zre = @view zfl[1:2:end-1]
zim = @view zfl[2:2:end]
zre, zim
end
reimvec (generic function with 1 method)
julia> @time reimvec(z);
0.000005 seconds (9 allocations: 400 bytes)
Như chúng ta có thể thấy, đằng sau hậu trường, một mảng như thế được strided:
julia> strides(reimvec(z)[1])
(2,)
Nguồn
2016-09-15 14:45:45
tôi nên đề cập rằng trừ mảng của bạn là rất lớn hay điều này xảy ra trong một vòng lặp rất chặt chẽ, đây là không thể tiết kiệm cho bạn quá nhiều thời gian - sao chép dữ liệu rất nhanh trên các CPU hiện đại. Nhưng có thể có một trường hợp sử dụng :) – StefanKarpinski
Bạn có thể nhận được * ít * phân bổ ít hơn bằng cách thả hoạt động 'reshape' và chỉ trả lại' xem (a, 1: 2: N), xem (a, 2: 2: N) '. Nó cũng làm cho mã một chút sạch hơn. Bạn có thể lưu một whooping 64 byte: D – DNF
@DNF Cảm ơn! Đã cập nhật. –