This should be possible with AOP using before() and after() to runt the time counting.
As it already got mentioned, one really is not in need of real Aspect-oriented Programming
in order to solve such tasks in JavaScript. But this language might deserve some more standardized
method-modifiers in addition to the already existing bind method.
Please check back with my 2 most recent posts on this matter:
... and how to implement it with the need of modifying the identification string "Function #1" automatically?
One does not need to since the console's time / timeEnd functionality only has to have
identical entry and exit points for measuring time (like the start/stop trigger of a stopwatch).
So one gets along with exactly the reference of the function/method one is currently running/measuring.
In order to solve the given task I will suggest around only instead of both before and
after for the former generates less overhead. The next code block exemplarily shows a
possible prototypal implementation. It also is the base for the afterwards following example
that finally might solve the OP's task.
(function (Function) {
  var
    isFunction = function (type) {
      return (
           (typeof type == "function")
        && (typeof type.call == "function")
        && (typeof type.apply == "function")
      );
    },
    getSanitizedTarget = function (target) {
      return ((target != null) && target) || null;
    }
  ;
  Function.prototype.around = function (handler, target) { // [around]
    target  = getSanitizedTarget(target);
    var proceed = this;
    return (isFunction(handler) && isFunction(proceed) && function () {
      return handler.call(target, proceed, handler, arguments);
    }) || proceed;
  };
}(Function));
The next example takes into account that method-modification essentially relies on
functionality that is bound to an object. It is not just function wrapping. In order
to not loose the context a method is operating on, context has to be delegated /
passed around as target throughout all operations.
For this the example does not modify calculate since it is not bound to an object
but it modifies trigger instead.
var testObject = {
  calculate: function (hugeInteger) {
    var
      i = hugeInteger,
      k = 0
    ;
    while (i--) {
      k++;
    }
    return k;
  },
  trigger: function (hugeInteger) {
    this.result = this.calculate(hugeInteger);
  },
  result: -1
};
console.log("testObject.result : ", testObject.result);
console.log("testObject.trigger(Math.pow(2, 26)) : ", testObject.trigger(Math.pow(2, 26))); // takes some time.
console.log("testObject.result : ", testObject.result);
console.log("testObject.someTrigger(0) : ", testObject.trigger(0)); // logs immediately after.
console.log("testObject.result : ", testObject.result);
testObject.trigger = testObject.trigger.around(function (proceed, interceptor, args) {
  // before:
  console.time(proceed);
  // proceed:
  proceed.apply(this, args);
  // after:
  console.timeEnd(proceed);
}, testObject); // omitting the 2nd argument - the [target] object - might break code that did work before.
console.log("testObject.trigger(Math.pow(2, 26)) : ", testObject.trigger(Math.pow(2, 26)));
console.log("testObject.result : ", testObject.result);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  (function (Function) {
    var
      isFunction = function (type) {
        return (
             (typeof type == "function")
          && (typeof type.call == "function")
          && (typeof type.apply == "function")
        );
      },
      getSanitizedTarget = function (target) {
        return ((target != null) && target) || null;
      }
    ;
    Function.prototype.around = function (handler, target) { // [around]
      target  = getSanitizedTarget(target);
      var proceed = this;
      return (isFunction(handler) && isFunction(proceed) && function () {
        return handler.call(target, proceed, handler, arguments);
      }) || proceed;
    };
  }(Function));
</script>