each server call probably costs around 0.3 seconds
for the client (without doing anything)… so if you can load a page with 1 server call it’s gonna massively improve things for the client.
for timing on the server I’d probably use a decorator because it makes the code less littered with print statements (adapted from stackoverflow timeit vs decorator)
ServerSide
from functools import wraps
from time import time
def timeit_server(f):
@wraps(f)
def wrap(*args, **kwargs):
str_args = ', '.join(str(arg) for arg in args)
str_kwargs = ', '.join(f"{k}={v}" for k,v in kwargs.items())
args_kwargs = f"{str_args}, {str_kwargs}" if args and kwargs else f"{str_args}{str_kwargs}"
timelog.print(f'{f.__name__}({args_kwargs}) called')
ts = time()
result = f(*args, **kwargs)
te = time()
timelog.print(f'{f.__name__} took: {te-ts:.4f} sec')
return result
return wrap
@anvil.server.callable
@timeit_server
def f(a): #example function
for _ in range(a):
i = 0
return -1
Client Side
And then something similar on the client side (without functools
and @wraps
) like:
def timeit(f):
def wrap(self, *args, **kwargs):
str_args = ', '.join(str(arg) for arg in args)
str_kwargs = ', '.join(f"{k}={v}" for k,v in kwargs.items())
args_kwargs = f"{str_args}, {str_kwargs}" if args and kwargs else f"{str_args}{str_kwargs}"
timelog.print(f'{self.__name__}.{f.__name__}({args_kwargs}) called')
ts = time()
result = f(self, *args, **kwargs)
te = time()
timelog.print(f'{self.__name__}.{f.__name__} took: {te-ts:.4f} sec')
return result
return wrap
class Form1(Form1Template):
@timeit
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
anvil.server.call('f',10000000)
I’ve also used the Logger
class from this post to create a timelog
Logger
so that I can turn it on and off whenever I need.
timelog = Logger(debug=True, msg="timelog:")
here’s a clone of how you might use it:
https://anvil.works/build#clone:BFS7ZTZI4H3OO2UL=N5URW5LHZMPDLTML6KQZDPK2
Output looks like: