FrontEnd/JavaScript

[JavaScript] 실행 시간 측정 - Date, console.time(), performance.now()

꼽파 2023. 12. 21. 15:37


자바스크립트에서 실행 시간을 측정하는 것은 코드의 성능을 평가하고 최적화하는 데 도움이 된다.

이를 통해 어떤 부분이 느린지 파악하고, 개선이 필요한 부분을 찾아낼 수 있다.

프로그래머스로 문제를 풀다보니 실행 시간을 측정하고 싶어서 방법이 없을까 생각하다보니 몇 가지 방법을 알게 되었다.

크게

  • Date
  • console.time()과 console.timeEnd()
  • performance.now()

를 활용하는 세 가지 방법이 있다.


Date

Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 담고 있다.

이를 활용하여 시작 시각과 종료 시각의 차를 계산할 수 있다.

const start = new Date();  // 시작

function solution(value) {
    // 내용
}

// 함수 실행
console.log(solution(value));

const end = new Date();  // 끝
const executionTime = end - start;
console.log("Execution time: " + executionTime + " milliseconds");  // 출력

 

한편 일반적인 사칙 연산을 사용하면 Date 객체는 숫자로 자동으로 변환되어 연산되는 것을 알 수 있다.

// 현재 일시
let date1 = new Date();
console.log(`date1, ${date1}`);
console.log(typeof(date1))  // date1의 데이터타입

// 1초 후에 date2 생성
setTimeout(() => {
  let date2 = new Date();
  console.log(`date2, ${date2}`);
    console.log(`date2 - date1, ${date2 - date1}`)  // 경과시간
    console.log(typeof(date2 - date1))  // (date2 - date1)의 데이터타입
}, 1000);

 

하지만 MDN의 문서를 살펴보면 자바스크립트로 경과시간을 계산하는 방식으로는 Date.now()getTime() 메소드를 사용하는 것을 알 수 있다. 두 가지 메소드 모두 숫자값을 리턴한다.

 

  • Date.now() : UTC 기준으로 1970년 1월 1일 0시 0분 0초부터 현재까지 경과된 밀리초(숫자)를 반환하는 메서드
  • Date.prototype.getTime() : 표준시에 따라 지정된 날짜의 시간에 해당하는 숫자 값을 반환하는 메서드

Date.now()

Date.now()는 UTC 기준으로 1970년 1월 1일 0시 0분 0초부터 현재까지 경과된 밀리초(숫자)를 반환한다.

// Date.now()

// 현재 일시
let start = Date.now();
console.log(`start, ${start}`);
console.log(typeof(start))  // start의 데이터타입

// 1초 후에 end 생성
setTimeout(() => {
  let end = Date.now();
  console.log(`end, ${end}`);
  console.log(`end - start, ${end - start}`)  // 경과시간
  console.log(typeof(end - start))  // (end - start)의 데이터타입
}, 1000);


Date.prototype.getTime()

getTime() 메서드는 표준시에 따라 지정된 날짜의 시간에 해당하는 숫자 값을 반환한다.

// getTime

// 현재 일시
let start = new Date();
console.log(`start, ${start}`);
console.log(typeof(start))  // start의 데이터타입

// 1초 후에 end 생성
setTimeout(() => {
  let end = new Date();
  console.log(`end, ${end}`);
  console.log(`end - start, ${end.getTime() - start.getTime()}`)  // 경과시간
  console.log(typeof(end - start))  // (end - start)의 데이터타입
}, 1000);

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date

 

Date - JavaScript | MDN

JavaScript Date 객체는 시간의 한 점을 플랫폼에 종속되지 않는 형태로 나타냅니다. Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 담습니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/API/setTimeout

 

setTimeout() - Web API | MDN

전역 setTimeout() 메서드는 만료된 후 함수나 지정한 코드 조각을 실행하는 타이머를 설정합니다.

developer.mozilla.org


console.time(), console.timeEnd()

 

console.time()
주어진 이름의 타이머를 실행한다.

하나의 페이지에서는 최대 10,000개의 타이머를 동시에 실행할 수 있다.

console.time(label);  // label 안에 타이머 이름이 들어감


console.timeEnd()
지정한 타이머를 멈추고, 소요시간을 출력한다.

 

변수 선언 없이 출력만 하면 된다.

console.time('executionTime');  // 시작

function solution(value) {
    // 내용
}

// 함수 실행
console.log(solution(value));

console.timeEnd('executionTime');  // 끝

 

// console.time()

console.time('Timer')  // 현재 시각

// 1초 후에 end 생성
setTimeout( () => {
  console.timeEnd('Timer')  // 소요 시간
}, 1000);

time과 timeEnd 안에 있는 타이머 이름이 같아야만 정상적으로 출력된다.

// console.time()
// 타이머 이름을 다르게 지정한 경우

console.time('good')  // 현재 시각

// 1초 후에 end 생성
setTimeout( () => {
  console.timeEnd('Timer')  // 소요 시간
}, 1000);

 

https://developer.mozilla.org/ko/docs/Web/API/console

 

console - Web API | MDN

console 객체는 브라우저의 디버깅 콘솔(Firefox 웹 콘솔 등)에 접근할 수 있는 메서드를 제공합니다. 동작 방식은 브라우저마다 다르지만, 사실상 표준으로 여겨지는 기능도 여럿 있습니다.

developer.mozilla.org


performance.now()

브라우저에서 제공하는 성능 측정을 위한 메서드 중 하나이다.
현재 시각을 나타내는 타임스탬프를 반환한다.

기본 단위는 밀리초(1/1000 초)이며, 부동 소수점 숫자로 나타낸다.

https://developer.mozilla.org/en-US/docs/Web/API/Performance

 

Performance - Web APIs | MDN

The Performance interface provides access to performance-related information for the current page.

developer.mozilla.org

const start = performance.now();  // 시작

function solution(value) {
    // 내용
}

// 함수 실행
console.log(solution(value));

const end = performance.now();  // 끝
console.log("Execution time: " + (end - start) + " milliseconds");  // 출력

 

밀리초의 단위가 정밀하게 나오는 걸 확인할 수 있다.

// performance.now()

const start = performance.now()  // 현재 시각

// 1초 후에 end 생성
setTimeout( () => {
  const end = performance.now()
  const elapsed = end - start
  console.log(elapsed)  // 소요 시간
}, 1000);

 

Math.round를 활용하여 소수점 둘째자리까지 출력하도록 하였다.

// console.time()

const start = performance.now()  // 현재 시각

// 1초 후에 end 생성
setTimeout( () => {
  const end = performance.now()
  const elapsed = end - start
    console.log(Math.round(elapsed * 100) / 100) // 소요 시간 (둘째자리까지)
}, 1000);


함수 실행시간이 반영된 코드

평균 20ms가 나온다.

 

함수 실행시간이 반영되지 않은 코드

평균 0.02ms가 나온다.

 

0.02 밀리 초와 20 밀리 초(0.02초)는 1000배 차이가 난다.

 

프로그래머스에서 함수 실행 시간 측정

const start = performance.now();  // 시작

    function solution(my_string) {

        const vowels = ["a", "e", "i", "o", "u"]
        var answer = '';
        // 문자열 split('')으로 배열로 만들기
        // 모음에 해당하는 원소는 넣지 않기

        answer = my_string.split('').filter(a => !vowels.includes(a)).join('');

        return answer;

        }

const end = performance.now();  // 끝
console.log("Execution time: " + (end - start) + " milliseconds");  // 출력

 

함수 실행하는 코드 에 end 변수와 출력 코드가 나와야 한다.

실행 순서가 바뀐 코드(0.023ms)와 프로그래머스의 코드 실행 시간(0.002ms)이 비슷하다.

→ 프로그래머스에서 출력을 할 때 실행 코드가 가장 밑부분에 있다는 것을 알 수 있다.

 

그러므로 위와 같은 방식으로 함수 실행을 측정하는 것이 불가능하다.

좋은 방법이 있는지 알아봐야겠다.

728x90