Decorate a function/method to check its timings.

    To use the function's name:
      @sw.decorate
      def func():
        pass

    To name it explicitly:
      @sw.decorate("name")
      def random_func_name():
        pass

    Args:
      name_or_func: the name or the function to decorate.

    Returns:
      If a name is passed, returns this as a decorator, otherwise returns the
      decorated function.

def decorate(self, name_or_func):
    """Decorate a function/method to check its timings.

    To use the function's name:
      @sw.decorate
      def func():
        pass

    To name it explicitly:
      @sw.decorate("name")
      def random_func_name():
        pass

    Args:
      name_or_func: the name or the function to decorate.

    Returns:
      If a name is passed, returns this as a decorator, otherwise returns the
      decorated function.
    """
    if os.environ.get("SC2_NO_STOPWATCH"):
      return name_or_func if callable(name_or_func) else lambda func: func

    def decorator(name, func):
      @functools.wraps(func)
      def _stopwatch(*args, **kwargs):
        with self(name):
          return func(*args, **kwargs)
      return _stopwatch
    if callable(name_or_func):
      return decorator(name_or_func.__name__, name_or_func)
    else:
      return lambda func: decorator(name_or_func, func)