I suspected that is what it was. I just filed https://github.com/JuliaLang/julia/issues/10278 to capture this discussion here, but I believe we do have issues open.
-viral On Sunday, February 22, 2015 at 1:34:59 PM UTC+5:30, Jameson wrote: > > 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. >>> >>> >>>
