스레드가 생성될 때 컴퓨터 내부적으로 운영체제(OS)가 요청을 받아들여 메모리공간을 확보해주고 그 메모리를 스레드에게 할당해준다. 스레드는 동일한 메모리영역에서 생성되고 관리되지만, 생성 및 수거에 드는 비용을 무시할 수 없다.
그렇기 때문에 요청이 들어올 때 마다 스레드를 생성하고 일을 다하면 수거하고 하는 작업은 프로그램 퍼포먼스에 지대한 영향을 줄 수 있다. 그래서 스레드를 미리 만들어 놓는 것이다.
퍼포먼스 향상을 위해 미리 스레드를 만들어 놓는 것
스레드풀을 사용하는 모듈에는 crypto, zlib, dns.lookup 등이 있다.
여기서는 crypto.pdkdf2 메서드로 확인한다.
const crypto = require('crypto');
const pass = 'pass';
const salt = 'salt';
const start = Date.now();
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('1:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('2:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('3:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('4:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('5:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('6:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('7:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('8:', Date.now() - start);
});
결과)
1: 1504
2: 1542
4: 1542
3: 1575
5: 3016
6: 3130
7: 3131
8: 3215
실행할 때 마다 시간과 순서가 달라진다. 스레드풀이 작업을 동시에 처리하므로 여덟 개의 작업 중에서 어느 것이 먼저 처리될 지 모른다. 1~4와 5~8은 각각 그룹으로 묶어져있고 5~8은 1~4보다 시간이 늦다는 것을 알 수 있다. 스레드풀이 네개 이므로 처음 네 작업이 동시에 실행되고, 그것들이 종료되면 다음 네 개의 작업이 실행된다. 그러나 컴퓨터의 코어 개수에 따라 다른 결과가 생길 수 있다.
윈도우라면 cmd에 SET UV_THREADPOOL_SIZE=1
를
맥과 리눅스라면 터미널에 UV_THREADPOOL_SIZE=1
를 입력한다
눈치를 챗겠지만 위 명령어는 스레드 풀 크기를 1로 설정해주는 것이다.
위 처럼 실행 한 후에는 작업이 한 번에 하나씩 처리된다.
다만 숫자를 크게 할 때는 컴퓨터 코어 개수와 같거나 많게 설정해야 뚜렷한 효과가 나타난다.
참고 자료 및 사이트 (감사합니다)
조현영님 노드js 교과서에 있는 예시인데 참고자료에는 누락된것 같네요~