TypedArray와 일반 배열과의 성능 차이 정리

2025. 8. 2. 18:46·개발 아카이브/Javascript
반응형

protobuf를 알아보다가 Uint8Array를 알게되고, 그러다가 TypedArray을 알게 되었다.
자바스크립트 쓰면서 타입이 없어 비효율이 많다는 점을 내면속에 알고만 있었는데, 이런 부분을 보완한 Array가 있다고 해서 알아봤다.
당연히 이런것들이 존재했을 법 한데, 새삼 이제야 알게된다.
TypedArray는 단순히 타입이 있는것 뿐만 아니라 많은 용도들이 있는데 신기해서 가져와 봄.

 

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

 

TypedArray - JavaScript | MDN

TypedArray 객체는 이진 데이터 버퍼에 기초하여 배열과 같은 보기를 만들어냅니다. 하지만 TypedArray라는 전역 속성은 존재하지 않으며, 직접 볼 수 있는 TypedArray 생성자도 존재하지 않습니다. 대신

developer.mozilla.org

 

TypedArray가 필요한 이유

일반 배열의 문제점

JavaScript의 일반 배열은 매우 유연하지만, 성능면에서 한계가 있음.

// 일반 배열: 타입이 섞여있고 메모리 비효율적
const normalArray = [1, "hello", 3.14, true, null];

// 메모리에서는 각 요소가 다른 타입으로 저장됨
// 숫자도 내부적으로는 64비트 부동소수점으로 저장

 

일반 배열의 한계:

  • 모든 숫자가 64비트 부동소수점으로 저장 (메모리 낭비)
  • 타입 체크 오버헤드
  • 메모리가 연속적이지 않을 수 있음
  • 바이너리 데이터 처리에 부적합

TypedArray의 장점

// TypedArray: 타입이 고정되고 메모리 효율적
const uint8Array = new Uint8Array([1, 2, 3, 255]);

// 각 요소가 정확히 1바이트씩 연속된 메모리에 저장
// 0~255 범위의 정수만 저장 가능

TypedArray 종류와 특징

정수형 TypedArray

타입 크기 범위 용도
Int8Array 1바이트 -128 ~ 127 부호있는 8비트 정수
Uint8Array 1바이트 0 ~ 255 부호없는 8비트 정수
Uint8ClampedArray 1바이트 0 ~ 255 (고정) 이미지 픽셀 데이터
Int16Array 2바이트 -32,768 ~ 32,767 부호있는 16비트 정수
Uint16Array 2바이트 0 ~ 65,535 부호없는 16비트 정수
Int32Array 4바이트 -2^31 ~ 2^31-1 부호있는 32비트 정수
Uint32Array 4바이트 0 ~ 2^32-1 부호없는 32비트 정수

부동소수점 TypedArray

타입 크기 정밀도 용도
Float32Array 4바이트 단정밀도 3D 그래픽, 게임
Float64Array 8바이트 배정밀도 과학 계산

특수한 Uint8ClampedArray

const normal = new Uint8Array([300, -10, 50]);
console.log(normal); // [44, 246, 50] - 오버플로우 발생

const clamped = new Uint8ClampedArray([300, -10, 50]);
console.log(clamped); // [255, 0, 50] - 범위에 고정됨

TypedArray 생성 방법

1. 길이로 생성

const buffer = new Uint8Array(4); // 4바이트 배열
console.log(buffer); // [0, 0, 0, 0]

2. 배열로 생성

const buffer = new Uint8Array([1, 2, 3, 4]);
console.log(buffer); // [1, 2, 3, 4]

3. ArrayBuffer로 생성

const arrayBuffer = new ArrayBuffer(4); // 4바이트 메모리
const uint8View = new Uint8Array(arrayBuffer);
const uint16View = new Uint16Array(arrayBuffer);

uint8View[0] = 255;
uint8View[1] = 255;
console.log(uint16View[0]); // 65535 (같은 메모리를 다른 방식으로 해석)

4. 다른 TypedArray로부터 생성

const original = new Uint32Array([1, 2, 3, 4]);
const copy = new Uint8Array(original.buffer); // 같은 메모리 공유

TypedArray vs 일반 배열 성능 비교

// 성능 테스트: 1백만 개 숫자 처리
const size = 1000000;

// 일반 배열
console.time('일반 배열');
const normalArray = new Array(size);
for (let i = 0; i < size; i++) {
  normalArray[i] = i % 256;
}
console.timeEnd('일반 배열'); // ~50ms

// TypedArray
console.time('Uint8Array');
const typedArray = new Uint8Array(size);
for (let i = 0; i < size; i++) {
  typedArray[i] = i % 256;
}
console.timeEnd('Uint8Array'); // ~20ms

// 메모리 사용량
console.log('일반 배열 메모리:', normalArray.length * 8, '바이트'); // 8MB
console.log('TypedArray 메모리:', typedArray.byteLength, '바이트'); // 1MB

실제 사용 사례

여기는 알아보다가 안쓸것 같지만 그렇구나 싶었다. 바이너리를 이해하면 많은걸 할 수 있구나 싶더라.

1. 파일 처리

// 파일을 바이너리로 읽기
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (event) => {
  const file = event.target.files[0];
  const arrayBuffer = await file.arrayBuffer();
  const uint8Array = new Uint8Array(arrayBuffer);

  console.log('파일 크기:', uint8Array.length, '바이트');
  console.log('첫 4바이트:', uint8Array.slice(0, 4));
});

2. 이미지 픽셀 조작

// Canvas에서 이미지 데이터 가져오기
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

// Uint8ClampedArray로 픽셀 데이터 접근
const pixels = imageData.data; // [R, G, B, A, R, G, B, A, ...]

// 이미지를 흑백으로 변환
for (let i = 0; i < pixels.length; i += 4) {
  const avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
  pixels[i] = avg;     // Red
  pixels[i + 1] = avg; // Green
  pixels[i + 2] = avg; // Blue
  // pixels[i + 3]은 Alpha (투명도)
}

ctx.putImageData(imageData, 0, 0);

3. 네트워크 통신

// 바이너리 데이터 전송
const data = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"의 ASCII

fetch('/api/binary', {
  method: 'POST',
  body: data,
  headers: {
    'Content-Type': 'application/octet-stream'
  }
});

4. WebGL과 3D 그래픽

// 3D 좌표 데이터
const vertices = new Float32Array([
  -1.0, -1.0,  0.0,  // 점 1
   1.0, -1.0,  0.0,  // 점 2
   0.0,  1.0,  0.0   // 점 3
]);

// WebGL 버퍼에 데이터 전송
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

주의사항과 팁

1. 범위 오버플로우

const uint8 = new Uint8Array([300]); // 300은 255를 초과
console.log(uint8[0]); // 44 (300 % 256 = 44)

// 안전한 값 할당
function safeAssign(array, index, value) {
  array[index] = Math.max(0, Math.min(255, value));
}

2. 메모리 효율적인 복사

// 비효율적인 방법
const copy1 = new Uint8Array([...original]);

// 효율적인 방법
const copy2 = new Uint8Array(original.length);
copy2.set(original);

// 가장 빠른 방법 (같은 타입일 때)
const copy3 = original.slice();

3. 기타.

엔디안이란 개념도 보였는데 이건 잘 이해를 못해서 패스..
말로는 멀티바이트 데이터를 메모리에 저장하는 순서를 말한다고 함.

언제 TypedArray를 사용해야 할까?

사용하면 좋은 경우

  • 바이너리 데이터 처리: 파일, 이미지, 오디오
  • 대용량 숫자 배열: 과학 계산, 데이터 분석
  • 메모리 효율성이 중요한 경우: 게임, 실시간 애플리케이션
  • WebGL/Canvas 작업: 3D 그래픽, 이미지 처리
  • 네트워크 통신: Protocol Buffers, 바이너리 API

일반 배열을 사용하는 경우

  • 다양한 타입이 섞인 데이터
  • 문자열과 숫자가 함께 있는 경우
  • 작은 크기의 배열 (수십 개 이하)
  • 복잡한 객체를 저장하는 경우

결론

TypedArray는 JavaScript에서 바이너리 데이터와 대용량 숫자 배열을 효율적으로 처리할 수 있다. 특히 웹에서 파일 처리, 이미지 조작, 3D 그래픽, 실시간 데이터 처리 등의 작업을 할 때 필수.

  • 메모리 효율성: 일반 배열보다 8배 적은 메모리 사용
  • 성능 향상: 2-3배 빠른 처리 속도
  • 타입 안정성: 정해진 범위의 값만 저장
  • 바이너리 호환성: C/C++ 등 다른 언어와 데이터 교환 용이
반응형
저작자표시 비영리 변경금지 (새창열림)

'개발 아카이브 > Javascript' 카테고리의 다른 글

Uint8Array.from()이 반복문보다 빠른 이유  (1) 2025.08.02
protobufjs로 JSON보다 10배 빠른 데이터 통신하기  (0) 2025.08.02
크롬 AI 번역 API - Translator API  (7) 2025.07.25
Google Apps Script에 ChatGPT 연동하기  (3) 2024.07.24
[Sveltekit] 버튼 hover시 +page.server.js 실행을 막는 법  (0) 2024.06.17
'개발 아카이브/Javascript' 카테고리의 다른 글
  • Uint8Array.from()이 반복문보다 빠른 이유
  • protobufjs로 JSON보다 10배 빠른 데이터 통신하기
  • 크롬 AI 번역 API - Translator API
  • Google Apps Script에 ChatGPT 연동하기
운클라우드
운클라우드
프로그래밍, 디자인 및 각종 이야기와 리뷰를 담는 블로그
  • 운클라우드
    Wooncloud Blog
    운클라우드
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 이야기
        • 일기
        • 개발일지
        • 제품 리뷰
        • 기타
        • 정보처리기사
      • 정보
        • 유용한 사이트
      • 개발 아카이브
        • AI, 인공지능
        • Javascript
        • JAVA
        • DATABASE
        • 개발 관련 지식
        • 라이브러리
        • AWS, Cloud, Server
        • 코드 저장소
        • HTML, CSS
  • 블로그 메뉴

    • 홈
    • 방명록
    • 운구름 웹
    • 벨로그
    • 깃허브
    • 리틀리
    • 도시부엉
  • 링크

    • 홈페이지
    • 깃허브
    • 벨로그
  • 공지사항

  • 인기 글

  • 태그

    웹디자인
    자바스크립트
    CSS
    코드저장소
    튜닝
    스프링
    html
    json
    Ai
    스터디
    정보처리기사
    API
    javascript
    회고
    Java
    spring
    자바
    라이브러리
    SQL
    폰트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
운클라우드
TypedArray와 일반 배열과의 성능 차이 정리
상단으로

티스토리툴바