Passing args = (elements) is equivalent to args = elements, i.e. no tuple is created.
To pass a 1-element tuple, either do args = (elements,), or args = tuple([elements]).
performance - How much slower python classes are compared to their equivalent functions? - Stack Overflow
python - Minimising an objective function which is a method of a class - Stack Overflow
python - How to use scipy's minimize within a class? - Stack Overflow
python - class method as a model function for scipy.optimize.curve_fit - Stack Overflow
To answer the question: yes, it is likely to be a little slower, all else being equal. Some things that used to be variables (including functions) are now going to be object attributes, and self.foo is always going to be slightly slower than foo regardless of whether foo was a global or local originally. (Local variables are accessed by index, and globals by name, but an attribute lookup on an object is either a local or a global lookup, plus an additional lookup by name for the attribute, possibly in multiple places.) Calling a method is also slightly slower than calling a function -- not only is it slower to get the attribute, it is also slower to make the call, because a method is a wrapper object that calls the function you wrote, adding an extra function call overhead.
Will this be noticeable? Usually not. In rare cases it might be, say if you are accessing an object attribute a lot (thousands or millions of times) in a particular method. But in that case you can just assign self.foo to a local variable foo at the top of the method, and reference it by the local name throughout, to regain 99.44% of the local variable's performance advantage.
Beyond that there will be some overhead for allocating memory for instances that you probably didn't have before, but unless you are constantly creating and destroying instances, this is likely a one-time cost.
In short: there will be a likely-minor performance hit, and where the performance hit is more than minor, it is easy to mitigate. On the other hand, assuming your problem lends itself to an object-oriented solution, you could save hours in writing and maintaining the code. And saving time is likely why you're using a language like Python to begin with.
No.
In general you will not notice any difference in performance based on using classes or not. The different code structures implied may mean that one is faster than the other, but it's impossible to say which.
Always write code to be read, then if, and only if, it's not fast enough make it faster. Remember: Premature optimization is the root of all evil.
Here's how I would do it. Separate the function to be optimized from the class method and have a private static method for the payoff calculation that both methods can utilize.
import numpy as np
from scipy.optimize import minimize
class Player:
def __init__(self):
self.action = np.random.choice(np.linspace(0, 1, 11))
@staticmethod
def _calc_payoff(a, b):
if a < b:
return (1 - a) * a
elif a == b:
return 0.5 * (1 - a) * a
else:
return 0
def payoff(self, other):
return self._calc_payoff(self.action, other.action)
def best_reply(self, other):
f = lambda x: 1 - self._calc_payoff(x, other.action)
br = minimize(f, 0.5)
return br.x.item()
A = Player()
B = Player()
print(A.best_reply(B))
Is 0.5 the correct result?
payoff is a method and you cannot do math operations with methods, only with the return values of them. Just like Python can't calculate what -print is, it can't calculate what -self.payoff is.
For the second error refer to the documentation of the minimize method. I think the problem is that you need to change how you call minimize. Try this and please post the result:
br = minimize(self.payoff, 0.5, (other,))
Hi Pythonistas,
I'm interested in learning what optimization techniques you know for python code. I know its a general statement, but I'm interested in really pushing execution to the maximum.
I use the following -
-
I declare
__slots__in custom classes -
I use typing blocks for typing imports
-
I use builtins when possible
-
I try to reduce function calls
-
I use set lookups wherever possible
-
I prefer iteration to recursion
Edit: I am using a profiler, and benchmarks. I'm working on a library - an ASGI Api framework. The code is async. Its not darascience. Its neither compatible with pypy, nor with numba..
What else?