How to render Mandelbrot Set faster?
Setting one pixel at a time is likely the main source of the slowdown. Instead of calling put for each pixel, computer a whole row of pixels, or an entire matrix of pixels, and then call put one time at the end of the loop.
You can find an example here, among other places: https://web.archive.org/web/20170512214049/http://tkinter.unpythonic.net:80/wiki/PhotoImage#Fill_Many_Pixels_at_Once
Here is my code, it draws a 640x480 Mandelbrot in 8-9 seconds.
It does up to 256 iterations per pixel, uses a color map list, 'puts' only once to PhotoImage
and doesn't rely on symetry, so it could show any zoomed area of the set.
It's a pity that Tkinter doesn't allow access to the raster information of PhotoImage
as a buffer and that the clumsy string is required.
from tkinter import Tk, Canvas, PhotoImage,NW,mainloop from time import clockdef mandel(kx,ky): """ calculates the pixel color of the point of mandelbrot plane passed in the arguments """ global clr maxIt = 256 c = complex(kx, ky) z = complex(0.0, 0.0) for i in range(maxIt): z = z * z + c if abs(z) >= 2.0: return (255-clr[i],0,0) return(0,0,0)def prepare_mdb(xa,xb,ya,yb): """ pre-calculates coordinates of the mandelbrot plane required for each pixel in the screen""" global x,y,xm,ym xm.clear ym.clear xm=[xa + (xb - xa) * kx /x for kx in range(x)] ym=[ya + (yb - ya) * ky /y for ky in range(y)]x=640y=480#corners of the mandelbrot plan to display xa = -2.0; xb = 1.0ya = -1.5; yb = 1.5#precalculated color tableclr=[ int(255*((i/255)**12)) for i in range(255,-1,-1)]xm=[]ym=[]prepare_mdb(xa,xb,ya,yb)#Tk window = Tk()canvas = Canvas(window, width = x, height = y, bg = "#000000")t1=clock()img = PhotoImage(width = x, height = y)canvas.create_image((0, 0), image = img, state = "normal", anchor = NW)pixels=" ".join(("{"+" ".join(('#%02x%02x%02x' % mandel(i,j) for i in xm))+"}" for j in ym))img.put(pixels)canvas.pack()print(clock()-t1)mainloop()
Pure python is not that fast for numeric code. The easiest way to speed things up would be to use PyPy. If that is not fast enough, vectorize your algorithms using numpy. If that is still not fast enough, use Cython, or consider rewriting it in C.