2

I've read that pop()/shift() is significantly more performant than using slice(). https://jsperf.com/pop-vs-slice/5

Here's my use case using slice():

proto.wrapErrorFirst = proto.wrapErrFirst = function (fn: Function) {
  const self = this;
  return function (err: IPseudoError) {
    if (err) {
      return self.__handle(err, false);
    }
    try {
      // remove the error-first argument
      return fn.apply(this, Array.from(arguments).slice(1));
    }
    catch (err) {
      return self.__handle(err, false);
    }
  }
};

so this should be more performant:

  proto.wrapErrorFirst = proto.wrapErrFirst = function (fn: Function) {
      const self = this;
      return function (err: IPseudoError) {
        if (err) {
          return self.__handle(err, false);
        }
        try {
          const args = Array.from(arguments);
          args.shift()
          return fn.apply(this, args);
        }
        catch (err) {
          return self.__handle(err, false);
        }
      }
    };

but I am wondering if there is a way to do that with less code and perhaps a way to do that without having to call Array.from(arguments)?

maybe something kinda crazy like this:

delete arguments[0];
return fn.apply(this, arguments);
Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • yeah I don't think that last idea (using `delete`) is going to work – Alexander Mills Dec 16 '17 at 01:11
  • 1
    Could you use a rest parameter instead? `function (err: IPseudoError, ...args) {` – 4castle Dec 16 '17 at 01:16
  • @4castle my question is not that clear, but I am looking for the most performant way to shift off the first argument from the arguments "array" and then apply arguments to another function – Alexander Mills Dec 16 '17 at 01:19
  • I got that. I was just suggesting that if you declare the function differently, there would be no need to mess with `arguments`. `args` would be the array you need. – 4castle Dec 16 '17 at 01:22
  • yeah, I have been there before, see this issue :) https://github.com/Microsoft/TypeScript/issues/20261 – Alexander Mills Dec 16 '17 at 01:23
  • TypeScript can make it less verbose but not more performant – Alexander Mills Dec 16 '17 at 01:23
  • 1
    shift is the fast way you can use splice or slice, but shift is faster at lest in chrome, delete is not proper for remove elements of an array [See more here](https://stackoverflow.com/questions/500606/deleting-array-elements-in-javascript-delete-vs-splice) – Ciro Spaciari Dec 16 '17 at 01:35
  • 2
    @AlexanderMills if you would repeat this operation thousands of time per sec I would understand the urge to improve performance but in your case it looks like an overkill to look for [optimizations](http://wiki.c2.com/?PrematureOptimization). – Nir Alfasi Dec 16 '17 at 01:41
  • yeah this question is about both saving lines of code and optimizing performance - it's not just about my use case, but other people's as well – Alexander Mills Dec 16 '17 at 03:33

2 Answers2

2

Pop/Shift is the fast way you can use splice or slice, but pop/shift is faster at lest in chrome, delete is not proper for remove elements of an array See more here.

Ciro Spaciari
  • 630
  • 5
  • 10
2

You create new array from arguments any way, but also you want to skip first element. Most efficient way to do it in your case is using slice method from Array.prototype on arguments. So you do not need create temporary array as in first case and then slice it, and you do not need remove first element as in second case.

proto.wrapErrorFirst = proto.wrapErrFirst = function (fn: Function) {
  const self = this;
  return function (err: IPseudoError) {
    if (err) {
      return self.__handle(err, false);
    }
    try {
      const args = Array.prototype.slice.call(arguments, 1);
      return fn.apply(this, args);
    }
    catch (err) {
      return self.__handle(err, false);
    }
  }
};
Ilya Rezvov
  • 914
  • 5
  • 13