Some things you just have to write in C++ to make them fast enough usable. However, my co-worker and I have found a really neat trick to make some things viable in Python that weren’t before.
Using OpenMaya.MScriptUtil, you can get SWIG array objects for most numeric types, which you can memoryMap directly into numpy by going through ctypes. So that means, when dealing with large arrays of numbers, you can sometimes bypass python altogether. Accessing the skin weights and displaying them in a QTableView was taking 3 or 4 seconds with MDoubleArrays. With this technique, we got it down to .2 sec.
You can set the data in the same way. Just get the reference numpy object, and fill it with whatever data you want.
Be very careful with this, though. Getting data by pointer in python doesn’t increment the reference count, so you can easily corrupt memory outside of your array if the MScriptUtil object gets garbage collected.
Example:
from maya import OpenMaya as om
from ctypes import c_double
import numpy as np
import time
start = time.time()
# create a dummy array for testing purposes
pa = [float(i) for i in range(1000000)]
util = om.MScriptUtil()
util.createFromList(pa, len(pa))
end = time.time()
print "Allocation and copying took:", end - start
start = time.time()
# cast the scrptUtil object to a swig double pointer
ptr = util.asDoublePtr()
# Cast the swig double pointer to a ctypes array
cta = (c_double * len(pa)).from_address(int(ptr))
# Memory map the ctypes array into numpy
out = np.ctypeslib.as_array(cta)
# ptr, cta, and out are all pointing to the same memory address now
# so changing out will change ptr
# for safety, make a copy of out so I don't corrupt memory
out = np.copy(out)
end = time.time()
print "Getting the numpy interface took:", end - start