If you have to deal with attributes on a large set of objects, learning a little API or at least avoiding PyMel, might be worth a try. Here are some test results and the code run to acquire them:
Searching 44.000 transforms, to see it they have a specific custom attr (where every fourth node has it..)
With API:
Time Taken: 0.839416478551
With CMDS:
Time Taken: 14.0579282427
With PyMel:
Time Taken: 26.2123000353
import maya.OpenMaya as OpenMaya
import maya.cmds as mc
import pymel.core as pm
import time
customAttr = "MyTag"
class Timer():
def __init__(self):
self.start = None
def __enter__(self):
self.start = time.clock()
def __exit__(self, type, value, traceback):
print 'Time Taken: {0}'.format(time.clock() - self.start)
print "\nSearching 44.000 transforms, to see it they have a specific custom attr (where every third node has it..)"
print "\nWith API:"
with Timer():
dagIt = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst, OpenMaya.MFn.kTransform)
nodesWithAttrAPI = list()
while not dagIt.isDone():
depNode = OpenMaya.MFnDagNode(dagIt.currentItem())
depNodeAttr = depNode.hasAttribute(customAttr)
if depNodeAttr:
path = OpenMaya.MDagPath()
depNode.getPath(path)
nodesWithAttrAPI.append(path.fullPathName())
dagIt.next()
print "\nWith CMDS:"
with Timer():
nodesWithAttrCMDS = list()
for transform in mc.ls(type="transform"):
if mc.attributeQuery(customAttr, node=transform, exists=True):
nodesWithAttrCMDS.append(transform)
print "\nWith PyMel:"
with Timer():
nodesWithAttrPyMel = list()
for transform in pm.ls(type="transform"):
if pm.attributeQuery(customAttr, node=transform, exists=True):
nodesWithAttrPyMel.append(transform)