[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25733] trunk/blender/source/blender/ python/intern/bpy_driver.c: speedup for driver execution, use PyUnicode_InternFromString() for variable names, cache hash and string -> unicode conversion for driver variables.
Campbell Barton
ideasman42 at gmail.com
Tue Jan 5 11:54:54 CET 2010
Revision: 25733
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25733
Author: campbellbarton
Date: 2010-01-05 11:54:54 +0100 (Tue, 05 Jan 2010)
Log Message:
-----------
speedup for driver execution, use PyUnicode_InternFromString() for variable names, cache hash and string -> unicode conversion for driver variables.
Modified Paths:
--------------
trunk/blender/source/blender/python/intern/bpy_driver.c
Modified: trunk/blender/source/blender/python/intern/bpy_driver.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_driver.c 2010-01-05 06:49:29 UTC (rev 25732)
+++ trunk/blender/source/blender/python/intern/bpy_driver.c 2010-01-05 10:54:54 UTC (rev 25733)
@@ -26,6 +26,8 @@
#include "DNA_anim_types.h"
+#include "BLI_listbase.h"
+
#include "BPY_extern.h"
#include "BKE_fcurve.h"
@@ -145,12 +147,15 @@
{
PyObject *driver_vars=NULL;
PyObject *retval= NULL;
+ PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */
+ PyObject *expr_code;
PyGILState_STATE gilstate;
DriverVar *dvar;
float result = 0.0f; /* default return */
char *expr = NULL;
short targets_ok= 1;
+ int i;
/* sanity checks - should driver be executed? */
if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/)
@@ -172,9 +177,32 @@
}
}
+ /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
+ if((driver->flag & DRIVER_FLAG_RECOMPILE) || (driver->expr_comp==NULL)) {
+ Py_XDECREF(driver->expr_comp);
+ driver->expr_comp= PyTuple_New(2);
+
+ expr_code= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
+ PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 0, expr_code);
+
+ /* intern the arg names so creating the namespace for every run is faster */
+ expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
+ PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
+
+ for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
+ PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
+ }
+
+ driver->flag &= ~DRIVER_FLAG_RECOMPILE;
+ }
+ else {
+ expr_code= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 0);
+ expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
+ }
+
/* add target values to a dict that will be used as '__locals__' dict */
driver_vars = PyDict_New(); // XXX do we need to decref this?
- for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
+ for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
PyObject *driver_arg = NULL;
float tval = 0.0f;
@@ -183,7 +211,8 @@
driver_arg= PyFloat_FromDouble((double)tval);
/* try to add to dictionary */
- if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) {
+ /* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
+ if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg)) { /* use string interning for faster namespace creation */
/* this target failed - bad name */
if (targets_ok) {
/* first one - print some extra info for easier identification */
@@ -198,19 +227,13 @@
}
}
-#if 0 // slow
+#if 0 // slow, with this can avoid all Py_CompileString above.
/* execute expression to get a value */
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
#else
- /* compile the expression first if it hasn't been compiled or needs to be rebuilt */
- if((driver->flag & DRIVER_FLAG_RECOMPILE) || (driver->expr_comp==NULL)) {
- Py_XDECREF(driver->expr_comp);
- driver->expr_comp= Py_CompileString(expr, "<bpy driver>", Py_eval_input);
- driver->flag &= ~DRIVER_FLAG_RECOMPILE;
- }
/* evaluate the compiled expression */
- if (driver->expr_comp)
- retval= PyEval_EvalCode(driver->expr_comp, bpy_pydriver_Dict, driver_vars);
+ if (expr_code)
+ retval= PyEval_EvalCode((PyCodeObject *)expr_code, bpy_pydriver_Dict, driver_vars);
#endif
/* decref the driver vars first... */
More information about the Bf-blender-cvs
mailing list