41

So we had the Discussion today in our company about +new Date() being good practice or not. Some prefer this way over new Date().getTime().

In my opinion, this is pretty convenient but on the other side one would say it's harder to read.

Are there any pros or cons besides the obvious "It's harder to understand for people not familiar with the unary operator"?

Julian Hollmann
  • 2,902
  • 2
  • 25
  • 44

5 Answers5

51

The getTime method appears to be a huge amount faster:

enter image description here

Why is this the case?

Here's what happens when you call the getTime method on a Date instance:

  1. Return the value of the [[PrimitiveValue]] internal property of this Date object.

Here's what happens when you apply the unary plus operator to a Date instance:

  1. Get the value of the Date instance in question
  2. Convert it to a Number
    1. Convert it to a primitive
      1. Call the internal [[DefaultValue]] method
James Allardice
  • 164,175
  • 21
  • 332
  • 312
  • Where did you get that stat? – Kevin Bowersox Jan 10 '13 at 10:30
  • @KevinBowersox - Yeah, http://jsperf.com. I've linked to the test case in the answer. – James Allardice Jan 10 '13 at 10:32
  • @KevinBowersox Theres a link in the answer. http://jsperf.com/get-time-vs-unary-plus – Curtis Jan 10 '13 at 10:32
  • Assuming speed is not an issue, do you happen to know if the shorter form is idiomatic? Thanks! – elliot42 Jan 28 '13 at 20:35
  • 1
    @elliot42 - I wouldn't say it was idiomatic, but it is commonly used and any JS developer should understand your intentions. Personally, I use it all the time. Saves typing numerous characters! – James Allardice Jan 28 '13 at 20:40
  • 1
    The Perf results shown are misleading as you would not keep getting the same time value from a single value/variable (you would have cached the time value once instead in that situation). In practice situations (where you need the time from a `new Date()`) the difference is not great at all (see new answer). – iCollect.it Ltd Jan 21 '15 at 10:52
10

After thinking about this the last years a lot I came to the conclusion that performance is not a factor here.

So here is the solution I prefer in terms of readability:

Date.now();

Julian Hollmann
  • 2,902
  • 2
  • 25
  • 44
8

I find that this type of code tends to often be called infrequently, so I thought it best to add tests for the inline usage you typically see:

e.g.

var t = (new Date()).getTime();

and

var t = +new Date();

The JSPerf results show these two are not much different in speed: http://jsperf.com/get-time-vs-unary-plus/7

enter image description here

The problem with the previous perf results are that the example is not practical. You would not keep getting the same now in practice. You would just store the getTime() result once if the now was not changing. As these new results show, the speed difference is not significant in the typical usage situation.

So I guess the general advice is, use either for one-off usage +new Date() being shorter, but (new Date()).getTime() is more readable (and a tad faster).

Date.now():

If you are going to use the newer Date.now(), you will want to implement the recommended shim to support older browsers from here

if (!Date.now) {
  Date.now = function now() {
    return new Date().getTime();
  };
}

(Although I am puzzled why they don't just use an anonymous function in that example)

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
1

IMHO, when there isn't much difference in performance, legibility should always win out. We should all be practicing WCTR "writing code to be read." Therefore, for me, this is best practice:

(new Date()).getTime();
CodeDreamer68
  • 420
  • 5
  • 10
0

It all depends on what you are comparing.

In fact, running .getTime a million times consecutively on the same date object is about as fast as reading a fixed variable a million times, which doesn't seem pertinant to any real code.

A more interesting test might compare the time it takes to return the time string from new dates in each iteration.

<!doctype html>
<html lang="en">
<head>
<meta charset= "utf-8">
<title>get time</title>


<script>
/*does n= +new Date() take longer than n= new Date().getTime()?*/
var score=[],runs;

function tests(arg){
    runs= parseInt(document.getElementsByTagName('input')[0].value)|| 100000;
    var A= [], i= runs, start= new Date(),n=1357834972984;
    while(i--){
        A.push(n);
    }
    if(arg!==true){
        score[0]= (new Date()- start);  
        setTimeout(tests0, 0);
    }
}
function tests0(){
    runs= parseInt(document.getElementsByTagName('input')[0].value)|| 100000;
    var A= [], i= runs, start= new Date();
    while(i--){
        A.push(+(start));
    }
    score[1]= (new Date()- start);
    setTimeout(tests1, 0);
}

function tests1(){
    var A= [], i= runs, start= new Date();
    while(i--){
        A.push(start.getTime());
    }
    score[2]= (new Date()- start);
    setTimeout(tests2, 0);
}
function tests2(){
    var A= [], i= runs, start= new Date();
    while(i--){
        A.push(+(new Date));
    }
    score[3]= (new Date()- start);
    setTimeout(tests3, 0);
}
function tests3(){
    var A= [], i= runs, start= new Date();
    while(i--){
        A.push(new Date().getTime())
    }
    score[4]= (new Date()- start);
    setTimeout(report, 0);
}
function report(){ 
    var inp=document.getElementsByTagName('input'),t,
    lab=document.getElementsByTagName('label')
    for(var i=0;i<5;i++){
        inp[i+1].value=score[i]+' msec';
    }
}
onload= function(){
    tests(true);
    document.getElementsByTagName('button')[0].onclick=tests;
}
</script>
</head>
<body>
<h1>Comparing +prefix and getTime()</h1>
<p>
This comparison builds an array of the values for each test case, eg, 100000 array items for each case.
</p>
<ol>
<li>Building an array of a fixed integer, no date calculations at all.</li>
<li>Reading +prefix of existing Date and adding each value to array.</li>
<li>Reading getTime from existing Date and adding each value to array.</li>
<li>Creating a new date with +(new Date) and adding each value to array.</li>
<li>Creating a new date with new Date().getTime()and adding each value to array.</li>
</ol>
<p><label>Iterations of each test:<input type="text" size="8" value="100000"></label>
<button type="button">Run Tests</button></p>
<p><label>1. Building the array with no calculation: <input type="text" size="12"></label></p>
<h2>Repeatedly reading the same created date</h2>
<p><label>2. +prefix to existing Date: <input type="text" size="12"></label></p>
<p><label>3. getTime from existing Date: <input type="text" size="12"></label></p>
<h2>Creating a new date and reading new value each time:</h2> 
<p><label>4. +(new Date): <input type="text" size="12"></label></p>
<p><label>5. new Date().getTime(): <input type="text" size="12"></label></p>
</body>
</html>
kennebec
  • 102,654
  • 32
  • 106
  • 127