views:

81

answers:

2

I have spent many hours trying to figure what is going on here.

The function 'grad_logp' in the code below is called many times in my program, and cProfile and runsnakerun the visualize the results reveals that the function grad_logp spends about .00004s 'locally' every call not in any functions it calls and the function 'n' spends about .00006s locally every call. Together these two times make up about 30% of program time that I care about. It doesn't seem like this is function overhead as other python functions spend far less time 'locally' and merging 'grad_logp' and 'n' does not make my program faster, but the operations that these two functions do seem rather trivial. Does anyone have any suggestions on what might be happening?

Have I done something obviously inefficient? Am I misunderstanding how cProfile works?

def grad_logp(self, variable, calculation_set ):

    p = params(self.p,self.parents)

    return self.n(variable, self.p)

def n (self, variable, p ):
    gradient = self.gg(variable, p)

    return np.reshape(gradient, np.shape(variable.value))
def gg(self, variable, p):
    if variable is self:

        gradient = self._grad_logps['x']( x = self.value,  **p)
    else:
        gradient = __builtin__.sum([self._pgradient(variable, parameter, value, p) for parameter, value in self.parents.iteritems()])

    return gradient
+3  A: 

Functions coded in C are not instrumented by profiling; so, for example, any time spent in sum (which you're spelling __builtin__.sum) will be charged to its caller. Not sure what np.reshape is, but if it's numpy.reshape, the same applies there.

Alex Martelli
Huh, cProfile gives me times spent inside sum, and reshape. Do these numbers mean something else? They are both reported as fairly fast.
John Salvatier
@John, I guess `cProfile` has evolved since I last used and studied it in depth, but I don't see any other explanation -- beyond calls to other functions, those two methods do really very little.
Alex Martelli
+1  A: 

Your "many hours" might be better spent making your code less like a maze of twisty little passages and also documenting it.

The first method's arg calculation_set is NOT USED.

Then it does p = params(self.p,self.parents) but that p is NOT USED.

variable is self???

__builtin__.sum???

Get it firstly understandable, secondly correct. Then and only then, worry about the speed.

John Machin
Haha, a fair criticism. This code is mangled because I have removed some code in an attempt to figure out what is going on. I should have probably taken out the extra parameter too, but 'variable is self' and the use of the builtin sum both are necessary. the non-use of p was a mistake however, thanks!
John Salvatier