There's currently a known issue with the way operators (like +) get codegen'd for many arguments that can cause this sort of performance issue. There's definite plans to fix this. For now, simply splitting consecutive applications of + onto separate lines should resolve it.
On Sun Feb 22 2015 at 2:59:07 AM Viral Shah <[email protected]> wrote: > The memory usage balloons once the expression becomes bigger: > > julia> g(a0,a1,a2,a3,a4,x) = for i=1:10^6; f = a0 + a1*x +a2*x^2 + a3*x^3; > end > g (generic function with 3 methods) > > julia> @time g(1.0,1.0,1.0,1.0,1.0,1+im) > elapsed time: 0.011524283 seconds (104 bytes allocated) > > As soon as I introduce the x^4 term, I get: > > julia> g(a0,a1,a2,a3,a4,x) = for i=1:10^6; f = a0 + a1*x +a2*x^2 + a3*x^3 > + a4*x^4; end > g (generic function with 3 methods) > > julia> @time g(1.0,1.0,1.0,1.0,1.0,1+im) > elapsed time: 0.081671568 seconds (129 MB allocated, 10.74% gc time in 6 > pauses with 0 full sweep) > > -viral > > > > On Sunday, February 22, 2015 at 7:14:22 AM UTC+5:30, DumpsterDoofus wrote: > >> I wrote a simple script for a Schroder fractal (a distant cousin of >> Newton fractals) of a fourth-order polynomial: >> function SchroderFourth(a0::Float64, a1::Float64, a2::Float64, >> a3::Float64, a4::Float64, c::Complex{Float64}) >> x = c >> x2 = c >> M = 100 >> R = 10.0^-6 >> a = 0.1 >> for j in 1:M >> x2 = x >> f = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 >> fP = a1 + 2*a2*x + 3*a3*x^2 + 4*a4*x^3 >> fPP = 2*a2 + 6*a3*x + 12*a4*x^2; >> x = x - f*fP/(fP^2 - fPP*f) >> if abs(x - x2) < R >> return exp(-a*(j - (log(abs(x - x2))-log(R))/log(R)) + angle(x)im) >> end >> end >> return 0.0 + 0.0im >> end >> >> I tested it using @time as follows: >> @time arr = [SchroderFourth(1.0,2.0,3.0,4.0,5.0,x+y*im) for x in >> linspace(-2,2,1000), y in linspace(-2,2,1000)]; >> resulting in >> elapsed time: 3.371773428 seconds (2239441280 bytes allocated, 48.23% gc >> time) >> >> So it's allocating 2.2GB throughout the computation, and half the time is >> gc time. I have heard that sometimes this is caused by type instability, >> but the SchroderFourth function is type-stable (always returns >> Complex{Float64}). Am I committing any "great sins" in my implementation? >> >> Given that the array has 1M computations, and each computation loops at >> most M=100 loops, I suppose it's possible that gigabytes of allocation >> could occur if a memory address was gobbled up after each iteration of the >> loop. In comparison, running the same computation on the (simpler) "mandel" >> fractal on the JuliaLang website gives much less memory allocation (8MB): >> function mandel(z) >> c = z >> maxiter = 80 >> for n = 1:maxiter >> if abs(z) > 2 >> return n-1 >> end >> z = z^2 + c >> end >> return maxiter >> end >> @time arr = [mandel(x+y*im) for x in linspace(-2,2,1000), y in >> linspace(-2,2,1000)]; >> giving >> elapsed time: 0.123358763 seconds (8016176 bytes allocated) >> >> Any clues as to the large disparity in memory allocation between the two >> functions? I assume I'm doing something dumb that's causing memory to be >> allocated and gc'ed after each iteration, but am having trouble finding >> what is causing it. >> >> >>
