From: John H. <jdh...@ac...> - 2004-12-20 19:09:57
|
>>>>> "John" == John Hunter <jdh...@ac...> writes: John> This change alone gives me more than a 2x speedup. So with John> GTKAgg + a custom normalizer (in this case a do nothing John> normalizer) you'll be running 4-5 times faster than you were John> before, me thinks. Of the remaining time, about half of it, on my system, is spent in the colormapping. Almost all of this is in LinearSegmentedColormap.__call__, and is split between these numerix methods 0.12s zeros : create the RGBA colormapped output array 0.23s where : make sure the data are in the [0,1] interval 0.49s take + makeMappingArray - actually doing the mapping You may not want or need some of the overhead and extra checking that matplotlib does in the colormapping. Do you want colormapping at all by the way? If not, you can special case colormapping by simply converting to RGB in the 0-255 interval. Note, as I said it is a bit inelegant that everything has to go through RGB even if you don't need it. I have some ideas here, but that will have to wait a bit. from pylab import * def mynorm(X): return X class mycmap: name = "my gray" def __call__(self, X, alpha=None): # what is the fastest way to make an MxNx3 array simply # duplicating MxN on the last dimension? m,n = X.shape Z = zeros((m,n,3), typecode=X.typecode()) Z[...,0] = X Z[...,1] = X Z[...,2] = X return Z #norm = None # default norm = mynorm #cmap = None # default cmap = mycmap() ion() rc('figure', figsize=(13,12)) X = rand(1600,1600) figimage(X, cmap=cmap, norm=norm) With the following numbers # default cmap peds-pc311:~/python/projects/matplotlib> time python ~/test.py --numarray -dGTKAgg 1.630u 0.430s 0:02.12 97.1% 0+0k 0+0io 4746pf+0w # custom cmap peds-pc311:~/python/projects/matplotlib> time python ~/test.py --numarray -dGTKAgg 1.080u 0.290s 0:01.42 96.4% 0+0k 0+0io 4745pf+0w Of this 1.42 seconds, the big chunks are 0.660 The time it takes to do from pylab import *; half of this is initializing the colormaps and dicts in cm. We should do some work to get this number down. But it is a fixed cost that doesn't scale with array size 0.320 RandomArray2.py:97(random) # creating the dummy data. We can ignore this 0.540 backend_gtkagg.py:33(draw) # this creates the entire figure, of this, 0.420s is in the function FigureImage.make_image, most of which is in the extension code _image.fromarray So ignoring for now the fixed cost of loading modules and creating your arrays (Eg by running in pylab using the "run" function you only pay the module loading costs once), the next place where a big win is going to come from is in optimizing fromarray. Note, the matplotlib figure canvas is a drawable widget. If you want bare metal speed and don't want any of the features matplotlib offers (interpolation, normalization, colormapping, etc), you can always dump your image directly to the gtk canvas, especially if you compile gtk with image support. This may be useful enough for us to consider a backend figimage pipeline which would bypass a number of extra copies. Currently we have for gtkagg numarray -> agg image buffer -> figure canvas agg buffer -> gtk canvas With some care, we might be able to simplify this, ideally doing for the canvas numarray -> gtk canvas # for screen numarray -> agg buffer # for dumping to PNG There are some subtleties to think through as to how this would work. It would probably need to be a canvas method and not a renderer method, for one thing, which would take a bit of redesign. And then Midas would have to watch its back! JDH |