-2

I'm looking to create a function that will return how long it takes to execute any other function (maybe it can be done with a library but in principle I'm looking to implement it natively). I am looking to implement it in a native way), a priori it seems easy and it could be done either with decorators or with a classic function that receives a function by parameter:

def get_function_time(function):
   start_time = time.time()
   function()

return time.time() - start_time

Of course, this only would work with functions without parameters, in that case we could tell it to pass the arguments for the function:

def get_function_time(function, parameter):
   start_time = time.time()
   function(parameter)

return time.time() - start_time

Here we would have the same problem when calling functions with more or less parameters than one. Then my doubt comes here, is there a way with decorators or without them that according to the number of elements I send the same number of argmuments in the function.

For some tests that I needed to do I implemented this crappy solution that taking into account that I didn't have functions with more than 5 argmuents. functions of more than 5 argmuentos served me.

def get_function_time(function, parameters: list):

   start = time.time()

   parameters_num = len(parameters)
   if len(parameters) > 6: raise ValueError("Max 5 arguments")

   if parameters_num == 0:
        function()
   elif parameters_num == 1:
        function(parameters[0])
   elif parameters_num == 2:
        function(parameters[0], parameters[1])
   elif parameters_num == 3:
        function(parameters[0], parameters[1], parameters[2])
   elif parameters_num == 4:
        function(parameters[0], parameters[1], parameters[2], parameters[3])
   elif parameters_num == 5:
        function(parameters[0], parameters[1], parameters[2], parameters[3], parameters[4])

   return time.time() - start

But I was left with the question of how to do it in a dynamic way being able to measure any function no matter its arguments (as long as they are passed their arguments well, of course).

Sorry if the way of writing the question is not the best, I don't have much experience around here.

offerrall
  • 9
  • 2

1 Answers1

0

If I get it right, what you need is *args and **kwargs, which means arguments by orders and arguments by keywords.

For example

def get_function_time(function, *args, **kwargs):

    start = time.time()
    function(*args, **kwargs)
    return time.time() - start

then you can use it like this

get_function_time(function, 'abc', 'def', keyword1='ghi', keyword2='jkl')

this is equivalent to calling function as

function('abc', 'def', keyword1='ghi', keyword2='jkl')
Brandon
  • 708
  • 6
  • 13
  • That's right, it works! I thought about it but discarded it because I mistakenly thought that if the original function did not have that *args, **kwargs format, **kwargs would not apply. In the end it has been much easier than I thought, Thank you very much! – offerrall Jun 22 '22 at 04:04
  • @offerrall Happy to help! If you find this answer works, could you please mark it as accepted? Thanks. – Brandon Jun 22 '22 at 04:11
  • I wasn't there yet because I had to wait a minimum of 5 minutes :) – offerrall Jun 22 '22 at 04:13