Wesley Brooks wrote: > Firstly tuples vs lists. I'm guessing that lists use more memory than > tuples as they provide more functions? Are they also more CPU intensive > to use?
First the requisite caveats about optimization: 1. Don't optimize until you have a demonstrated performance problem. 2. Don't optimize until you have profiled to identify the location of the bottleneck. 3. Timing your code is the only way to know if an optimization is successful. I don't know about memory usage. I haven't heard of a significant difference in timing between tuples and lists for data that doesn't change, but the best way to get a correct answer is to time operations of interest. See the timeit module for the best way to do this. For example, it seems that indexing a tuple is slightly slower than indexing a list: D:\Projects\e3po>python -m timeit -s "l = range(10)" "x=l[3]" 10000000 loops, best of 3: 0.0728 usec per loop D:\Projects\e3po>python -m timeit -s "l = tuple(range(10))" "x=l[3]" 10000000 loops, best of 3: 0.0797 usec per loop If you use tuples for something where you are changing the contents, so you have to create new tuples, my guess is that a list will be faster, but again, the only way to know for sure is to time it. For example, replacing an element of a tuple (which requires building a new tuple) is much more expensive than replacing an element of a list: D:\Projects\e3po>python -m timeit -s "l = range(10)" "l[3] = 5" 1000000 loops, best of 3: 0.087 usec per loop D:\Projects\e3po>python -m timeit -s "l = tuple(range(10))" "l= tuple(l[:3] + (5,) + l[4:])" 1000000 loops, best of 3: 1.05 usec per loop Similarly, extending a list, which can be done is place, is much less expensive than extending a tuple, which requires creating a new tuple: D:\Projects\e3po>python -m timeit -s "l = range(10)" "l.append(5)" 1000000 loops, best of 3: 0.262 usec per loop D:\Projects\e3po>python -m timeit -s "l = tuple(range(10))" "l= l+(5,)" 10000 loops, best of 3: 41.9 usec per loop > Currently if I'm not likely to add or remove Items I use a tuple > (eg, a coordinate in 3D space), but when I do I prefer using a list. > This leads on to another question: If you use an object many times, for > instance a list, does the interpreter remember that each new object is a > list and when a function is called on a list look at one section of > memory which details the list functions, or for each new object does it > dedicate a new section of memory to the functions of that object? In Python the methods of a class are stored with the class, not with instances of a class. When you create a new list, you use memory for the contents of the list and some overhead, but you don't create a new copy of all the list methods. > Secondly, a similar question to the first. A list object is something > which is in the standard python library. I guess in a CPython > distribution that this is C/C++ code being called by the python > interpreter when the list object is used? If so then this would imply > that a list object would be significantly quicker/less memory to use > than an equivalent object scripted in python. Quicker, yes; not sure about memory but it seems likely. It's pretty safe to say that code written in C and included with Python is faster than anything you can write. A major optimization technique is to move operations into built-in functions and classes. But again, the only way to know for sure is to test. D:\Projects\e3po>python -m timeit -s "import UserList;l = UserList.UserList(range(10))" "x=l[3]" 1000000 loops, best of 3: 0.697 usec per loop > I'm currently using lists > extensively to hold basic information within objects with additional > functions in the script to return information about items within the > list. My code would be a lot more elegant and easier to read if I used > custom objects for some of these but I'm worried they would be much > slower. Would it be appropriate to write a function that inherited the > methods of the List function? Would the new object retain the speed and > efficiency of the standard list object methods? You can subclass list. This should allow you to add custom operations but retain the speed of native lists. You can also write a wrapper class that contains a list and delegate many operations to it. (UserList in the standard library is an example of this.) In each case there will be a slight performance overhead but the basic list operations will still be fast. > > Lastly why can't python be compiled? I understand that there are certain > situations where it is preferable to leave the script readable or byte > code interpreted such as when programs are updated frequently over the > net, or are being distributed to computers with different operating > systems. What about situations where speed is critical? Is CPython's > interpreter effectively a C program that carries out C functions as > requested in the script? If so why is it not possible to have a program > that reads in the whole python script, translates it to C and compiles > it? Is it simply that the C functions are compiled already so carrying > out a complete compile would gain minimal increases in performance? The dynamic nature of Python makes it very hard to write a general Python compiler. This thread on c.l.py has a good summary of the issues and attempts to solve them: http://tinyurl.com/zsw9x If you have a performance problem, and you haven't been able to resolve it by tuning the Python code, you should look into these projects: psyco - dynamic runtime compiler, can generate significant speedups with very little effort pyrex - a Python-like language that makes it relatively easy to write Python extensions in C shedskin - compiles a restricted subset of Python to C++ http://mark.dufour.googlepages.com/home And of course you can also write a C extension that includes your time-critical code. Kent _______________________________________________ Tutor maillist - [email protected] http://mail.python.org/mailman/listinfo/tutor
