472,128 Members | 1,680 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,128 software developers and data experts.

Initialize lists; here's why

bartonc
6,596 Expert 4TB
Most other programming languages, as well as Python extension packages require arrays to be initialized to a particular size. Well, it turns out that there is an advantage to doing this with native python lists, too (that is, of course, if you know the size of the list beforehand).

I wrote two tests in a module (call it module1):
Expand|Select|Wrap|Line Numbers
  1. def listAppendTest(n):
  2.     aList = []
  3.     for i in range(n):
  4.         aList.append(i)
  5.  
  6. def listInitTest(n):
  7.     aList = [0] * n
  8.     for i in range(n):
  9.         aList[i] = 1
  10.  
In a second module I use timeit to check this theory:
Expand|Select|Wrap|Line Numbers
  1. import timeit
  2.  
  3. test1ExecStr = \
  4. """from module1 import listAppendTest
  5. listAppendTest(5)"""
  6.  
  7. t = timeit.Timer(test2ExecStr)
  8. print t.timeit()
  9.  
  10. # 22.7464275488
  11.  
  12. test2ExecStr = \
  13. """from module1 import listInitTest
  14. listInitTest(5)"""
  15.  
  16. t = timeit.Timer(test2ExecStr)
  17. print t.timeit()
  18.  
  19. # 17.7503707873
Interesting results, no?
Aug 9 '07 #1
4 11078
Your testing only five times? I doubt that is statistically sound. What happens when you try 1000?

In any case trying to micromanage performance like this is really the wrong way to programme. First, find if your app is not fast enough, then profile, then fix the bottleneck.

Remember the first rule of optimisation: Don't.
Aug 9 '07 #2
bvdet
2,851 Expert Mod 2GB
Your testing only five times? I doubt that is statistically sound. What happens when you try 1000?

In any case trying to micromanage performance like this is really the wrong way to programme. First, find if your app is not fast enough, then profile, then fix the bottleneck.

Remember the first rule of optimisation: Don't.
By my recollection, timeit() defaults to 1000000 iterations.

I routinely optimize as I program where possible. If I know a one method is more efficient than another, I use the most efficient, unless additional functionality is required. Occasionally I use timeit() just so I will know.

Would you use string concatenation repeatedly to build long strings or the string join method? Here's another example:

Method 1:
Expand|Select|Wrap|Line Numbers
  1. def __add__(self, other):
  2.         return Point(*[a+b for a,b in zip(self,other)])
Method 2:
Expand|Select|Wrap|Line Numbers
  1. def __add__(self, other):
  2.         return Point(self.x+other[0], self.y+other[1], self.z+other[2])
Which one should I use?
Aug 9 '07 #3
bartonc
6,596 Expert 4TB
Your testing only five times? I doubt that is statistically sound. What happens when you try 1000?

In any case trying to micromanage performance like this is really the wrong way to programme. First, find if your app is not fast enough, then profile, then fix the bottleneck.

Remember the first rule of optimisation: Don't.
How 'bout 5 million times?
Aug 10 '07 #4
bartonc
6,596 Expert 4TB
Most other programming languages, as well as Python extension packages require arrays to be initialized to a particular size. Well, it turns out that there is an advantage to doing this with native python lists, too (that is, of course, if you know the size of the list beforehand).

I wrote two tests in a module (call it module1):
Expand|Select|Wrap|Line Numbers
  1. def listAppendTest(n):
  2.     aList = []
  3.     for i in range(n):
  4.         aList.append(i)
  5.  
  6. def listInitTest(n):
  7.     aList = [0] * n
  8.     for i in range(n):
  9.         aList[i] = 1
  10.  
In a second module I use timeit to check this theory:
Expand|Select|Wrap|Line Numbers
  1. import timeit
  2.  
  3. test1ExecStr = \
  4. """from module1 import listAppendTest
  5. listAppendTest(5)"""
  6.  
  7. t = timeit.Timer(test2ExecStr)
  8. print t.timeit()
  9.  
  10. # 22.7464275488
  11.  
  12. test2ExecStr = \
  13. """from module1 import listInitTest
  14. listInitTest(5)"""
  15.  
  16. t = timeit.Timer(test2ExecStr)
  17. print t.timeit()
  18.  
  19. # 17.7503707873
Interesting results, no?
Interestingly, (and this is something that I've been meaning to do for a long time) the import is taking a significant amount of time.
Expand|Select|Wrap|Line Numbers
  1. import timeit
  2.  
  3. test1ExecStr = \
  4. """from test3 import listAppendTest"""
  5.  
  6. t = timeit.Timer(test1ExecStr)
  7. print t.timeit()
  8.  
  9. # 8.945650355
  10.  
  11. test2ExecStr = \
  12. """from test3 import listInitTest"""
  13.  
  14. t = timeit.Timer(test2ExecStr)
  15. print t.timeit()
  16.  
  17. # 8.87637339383
Aug 10 '07 #5

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

3 posts views Thread by Matjaz | last post: by
11 posts views Thread by hana1 | last post: by
1 post views Thread by Little | last post: by
1 post views Thread by pasa_1 | last post: by
6 posts views Thread by artistlikeu | last post: by
10 posts views Thread by Anton Vredegoor | last post: by
4 posts views Thread by swtsvn | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.