[Bf-python] Optimizing Python scripts document draft

Campbell Barton cbarton at metavr.com
Wed Mar 30 00:57:25 CEST 2005


Hi All, this doc is ment to help people who are relativly new to python, 
to optimize python importers and exporters with some extra hints.
Feel free make any suggestions/corrections.
- Cam

*Writing Optimal Exporters and Importers for Blender:Python*



   1.

      *Getting Mesh data */(Exporting Only)/
      A recently added function removes the need for doing an
      ob.getData().name
      simply to get the name of the object.
      Instead use* obj.getData(1) ... meaning *obj.getData(1=name_only),
      this is nice because it works for all data types, its just that
      Mesh's are not just thin wrappers like most of the other Types in
      blender so you want to avoid mesh.getData() as much as possible,
      its best practice only
      calling each mesh data once.


   2.

      *Use new python functionality mesh.transform() / /*/(Exporting Only)/
      Of course this wasn't in python until 2 days ago :) but its very
      useful and on my PC is over 100 times faster then transforming each
      vert's location and normal by a matrix within python.
      make sure that if you are only exporting locations you add a 1,*
      mesh.transfrom(matrix, 1=location_only)* This avoids un-needed
      vertex normal transforming.


   3.

      *Be ware of python hogging memory.* /(python generally)/
      You may ignore this point though It has forced my into having 4
      gig of ram, so I take it seriously :) .


      A List in python (and therefor blender) is never? deallocated,
      python can re-use the memory whilst the script is running.

      Basically making large lists in python and a lot of recursive
      variable
      assignment can leak memory that can only be regained with a restart.
      - *If you can- avoid making large lists.

      This is Fixed in Python 2.4rc1, and will compile with blender.



   4.

      *Lists
      4.1 Removing List Items*/ (Python General)/

      If you have a list that you want to add onto another list, rather
      then appending in a for loop, try myList.extend([li1, li2...]).


      Use ls.pop(i) rather then ls.remove(listItem)

      This requires you to have the index of the list Item but is faster
      since remove needs to search the list.
      Using pop for removing list items favors a while loops instead of
      a for loop.


*4.2 Don't Copy Lists*/ (Python General)/

When passing a list/dictionary to a function, it is better to have the 
function modify the list rather then returning a new list.
This means python dosn't need to create a new list in memory.

Functions that modify a list in there place are more efficient then 
functions that create new lists.

normalize(vec) # faster: no re-assignment
...is usually faster then.
vec = normalize(vec) # slower, only use for functions that are used to 
make new, unlinked lists.



   5.

      *Pathnames */(Blender/Python)/
      Blender pathnames not compatible with python's open os.isfile etc
      python native functions don't understand blenders // as being the
      current file dir in blender.


   6.

      *Correct string parsing */(Import/Exporting)
      /Since many file formats are ASCII, the way you parse/export
      strings can make a large difference in how fast your program runs.
      When importing strings to make into blender there are a few ways
      to parse the string.

      *6.1 Passing String*

Use float(string) rather then eval(string) and if you know the value 
will be an int then int(string)
float() will work for an int too but its faster if ints are converted as 
ints.


*6.2 Checking String Start/End*

If your checking the start of a string for a keyword, use...

if line.startswith('vert '):
...rather then
if line[0:5] == 'vert ':

using Startswith is also less likely to raise errors because calling 
line[0:5]can raise errors if the string is less then 5 characters long.
String.endswith('foobar') can be used for line ending too.
Also, if your unsure weather the text is upper or lower case use lower 
or upper string function.
Eg.
if line.upper().startswith('VERT ')

   7.

      *Writing Strings to a File
      *
      There are 3 ways of joining a strings for writing/

      # Pythons string addition. Dont use if you can help it, especialy
      in the main data writing loop.
      file.write(str1 + ' ' + str2 + ' ' + str3 + '\n')

      # String formatting. Use this when your writing string data from
      floats and int's
      file.write('%s %s %s\n' % (str1, str2, str3))

      # Pythons string joining function. To join a list of strings
      file.write(' '.join([str1, str2, str3]) + '\n')

      join is fastest on many strings, string formatting is quite fast
      too (better for converting data types).

      And string arithmetic is slowest.





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.blender.org/pipermail/bf-python/attachments/20050330/01f095d1/attachment.html>


More information about the Bf-python mailing list