在Julia中,将结构体对象传递给函数并对其进行更改会分配内存。为什么?

huangapple go评论132阅读模式
英文:

Passing struct object in function and changing it allocates memory in Julia. Why?

问题

以下是您要求的代码部分的中文翻译:

  1. Base.@kwdef struct cyl_struct
  2. n::Int64
  3. a::Array{Float64} = Array{Float64}(undef,n,2);
  4. end
  5. function adder(cyl)
  6. for i in 1:cyl.n
  7. cyl.a[i,1] = 1.0;
  8. end
  9. end
  10. function adder2(a,n)
  11. for i in 1:n
  12. a[i,1] = 1.0;
  13. end
  14. end
  15. n = 1000;
  16. geom = cyl_struct(n=n);
  17. @btime adder(geom)
  18. @btime adder2(geom.a, geom.n)

运行这段代码会给出以下输出:

  1. 23.700 μs (489 allocations: 7.64 KiB)
  2. 594.444 ns (3 allocations: 80 bytes)

我的问题是,当我将结构体作为参数传递并在函数内部进行更改时,它会分配内存,但当我将各个数组作为参数传递时,它不会分配内存。为什么?如何以一种不分配内存的方式传递结构体对象,如果在函数内部进行修改时不分配内存。

英文:

The code I am playing around with is given below:

  1. Base.@kwdef struct cyl_struct
  2. n::Int64
  3. a::Array{Float64} = Array{Float64}(undef,n,2);
  4. end
  5. function adder(cyl)
  6. for i in 1:cyl.n
  7. cyl.a[i,1] = 1.0;
  8. end
  9. end
  10. function adder2(a,n)
  11. for i in 1:n
  12. a[i,1] = 1.0;
  13. end
  14. end
  15. n = 1000;
  16. geom = cyl_struct(n=n);
  17. @btime adder(geom)
  18. @btime adder2(geom.a, geom.n)

Running this code gives me the output:

  1. 23.700 μs (489 allocations: 7.64 KiB)
  2. 594.444 ns (3 allocations: 80 bytes)

My question is, when I pass the structure as argument and make changes inside it, it allocates memory, but when I pass the individual arrays as arguments, it doesn't allocate memory. Why? How can I pass the structure object in a way that it doesn't allocate memory if modified inside function.

答案1

得分: 1

代码正在替换结构体的一个成员。您可以通过广播赋值引用成员的元素:

  1. using BenchmarkTools
  2. Base.@kwdef struct cyl_struct
  3. n::Int64
  4. a::Array{Float64} = Array{Float64}(undef, n, 2);
  5. end
  6. function adder(cyl)
  7. for i in 1:n
  8. cyl.a[i, 1] = 1.0
  9. end
  10. end
  11. function adder1b(cyl)
  12. cyl.a[1:cyl.n, 1] .= 1.0
  13. end
  14. function adder2(a, n)
  15. for i in 1:n
  16. a[i, 1] = 1.0
  17. end
  18. end
  19. n = 1000
  20. geom = cyl_struct(n = n);
  21. @btime adder(geom)
  22. @btime adder1b(geom)
  23. @btime adder2(geom.a, geom.n)

结果为:

  1. 92.600 μs (1979 allocations: 46.56 KiB)
  2. 229.712 ns (2 allocations: 96 bytes)
  3. 686.755 ns (3 allocations: 80 bytes)
英文:

The code is replacing the a member of the struct. You can reference the member's elements via a broadcasted assignment instead:

  1. using BenchmarkTools
  2. Base.@kwdef struct cyl_struct
  3. n::Int64
  4. a::Array{Float64} = Array{Float64}(undef, n, 2);
  5. end
  6. function adder(cyl)
  7. for i in 1:n
  8. cyl.a[i, 1] = 1.0
  9. end
  10. end
  11. function adder1b(cyl)
  12. cyl.a[1:cyl.n, 1] .= 1.0
  13. end
  14. function adder2(a, n)
  15. for i in 1:n
  16. a[i, 1] = 1.0
  17. end
  18. end
  19. n = 1000
  20. geom = cyl_struct(n = n);
  21. @btime adder(geom)
  22. @btime adder1b(geom)
  23. @btime adder2(geom.a, geom.n)

Yields

  1. 92.600 μs (1979 allocations: 46.56 KiB)
  2. 229.712 ns (2 allocations: 96 bytes)
  3. 686.755 ns (3 allocations: 80 bytes)

huangapple
  • 本文由 发表于 2023年7月31日 23:09:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定