'Premature optimization'은 핑계일 뿐! 개발자의 게으름이 앱을 느리게 만든다.

by DD
2개월 전
조회수 20

'Premature optimization'의 잘못된 적용으로 인해 개발자들이 성능 저하를 간과하는 문제점을 지적하며, 기본적인 개발 역량 부족을 비판

N+1 쿼리(N+1 Query), **SELECT * 사용, 동기적 작업(Synchronous Work)** 등 성능 저하를 유발하는 일반적인 패턴을 구체적으로 제시

데이터베이스 조인(JOIN), Promise.all 사용, 가상화(Virtualization) 등 성능 개선을 위한 간단하고 효과적인 해결책을 제안

ORM(Object-Relational Mapping)과 최신 프레임워크(Framework)의 편리함이 오히려 성능 저하를 유발할 수 있음을 경고

성능 저하를 유발하는 개발 패턴

본문에서는 개발자들이 흔히 저지르는 실수로 인해 애플리케이션(Application)의 성능이 저하되는 여러 가지 패턴을 지적한다.

N+1 쿼리(N+1 Query): 반복문 내에서 데이터베이스(Database)를 호출하여 과도한 쿼리(Query)를 발생시키며, 응답 시간(Response Time)을 기하급수적으로 증가시킨다.

**SELECT * 사용: 불필요한 모든 컬럼(Column)을 선택하여 네트워크 트래픽(Network Traffic) 증가** 및 데이터베이스(Database) 부하를 가중시킨다.

동기적 작업(Synchronous Work): 서로 의존하지 않는 작업을 순차적으로 처리하여 전체 작업 시간(Total Execution Time)을 낭비한다.

이러한 패턴은 성능 저하의 주범이며, 코드의 가독성(Readability)을 해치지 않으면서도 쉽게 개선할 수 있다.

성능 개선을 위한 실용적인 해결책

글에서는 성능 저하 문제를 해결하기 위한 구체적인 방법들을 제시한다.

데이터베이스 조인(JOIN): N+1 쿼리(N+1 Query) 문제를 해결하기 위해 데이터베이스(Database)의 조인(JOIN) 기능을 활용하여 쿼리 수를 획기적으로 감소시킨다.

필요한 컬럼만 선택: SELECT * 대신 필요한 컬럼만 명시하여 데이터 전송량(Data Transfer)을 줄이고 메모리 사용량(Memory Usage)을 최적화한다.

Promise.all 사용: 병렬로 실행 가능한 비동기 작업(Asynchronous Task)을 동시에 실행하여 전체 작업 시간(Total Execution Time)을 단축한다.

이러한 방법들은 성능 개선(Performance Improvement)을 위한 기본적인 원칙이며, 개발자는 이를 숙지하고 적용해야 한다.

ORM과 프레임워크의 양면성

본문에서는 ORM(Object-Relational Mapping)과 최신 프레임워크(Framework)가 개발 생산성(Development Productivity)을 높이는 동시에 성능 문제를 야기할 수 있다고 지적한다.

Lazy Loading: ORM의 Lazy Loading 기능은 개발자가 명시적으로 쿼리를 작성하지 않아도 되게 하지만, N+1 쿼리(N+1 Query) 문제를 은밀하게 발생시킬 수 있다.

GraphQL Resolver: GraphQL(GraphQL)의 Resolver는 각 필드(Field)를 독립적으로 데이터베이스(Database)에 쿼리(Query)할 수 있어, 과도한 쿼리(Query)를 유발할 수 있다.

React Component: React(React) 컴포넌트(Component)가 독립적으로 데이터를 fetch하는 경우, 불필요한 데이터 요청(Data Request)을 발생시킬 수 있다.

결과적으로, 개발자는 프레임워크(Framework)의 편리함에 의존하기 전에 내부 동작 원리(Internal Mechanism)를 이해하고, 성능 문제를 예방하기 위한 노력을 기울여야 한다.

성능 최적화 vs. 기본 개발 역량

글에서는 'Premature optimization'과 '기본적인 개발 역량'을 구분하며, 성능 최적화에 대한 올바른 접근 방식을 제시한다.

Premature optimization: 성능 개선을 위해 코드의 가독성(Readability)을 해치거나, 불필요한 노력을 투입하는 행위

기본적인 개발 역량: N+1 쿼리(N+1 Query) 방지, 불필요한 데이터 로딩(Data Loading) 방지 등 성능 저하를 유발하는 기본적인 실수를 하지 않는 것

측정의 중요성: 성능 개선을 위한 노력은 반드시 측정(Measurement)을 기반으로 이루어져야 하며, 객관적인 데이터(Objective Data)를 통해 개선 효과를 검증해야 한다.

결론적으로, 성능 최적화는 중요하지만, 그 전에 기본적인 개발 역량을 갖추는 것이 우선이며, 'Premature optimization'이라는 핑계로 기본적인 실수를 정당화해서는 안 된다.

성능 개선을 위한 Best Practice

본문은 성능 개선을 위해 개발자가 지켜야 할 Best Practice를 제시한다.

코드 리뷰(Code Review) 강화: 동료 개발자(Developer)의 코드 리뷰(Code Review)를 통해 성능 저하를 유발하는 패턴을 사전에 방지하고, 코드 품질(Code Quality)을 향상시킨다.

프로파일링(Profiling) 도구 활용: 프로파일링(Profiling) 도구를 사용하여 병목 지점(Bottleneck)을 정확하게 파악하고, 최적화(Optimization) 대상을 선정한다.

지속적인 측정과 개선: 성능 개선은 일회성 작업이 아니라, 지속적인 측정(Measurement)과 개선(Improvement)을 통해 이루어져야 하며, 지속적인 모니터링(Monitoring) 시스템 구축이 필수적이다.

ORM/프레임워크(Framework)의 이해: ORM과 프레임워크(Framework)의 내부 동작 원리를 정확히 이해하고, 성능 저하를 유발하는 패턴을 피하도록 노력해야 한다.

Premature Optimization Is Bad, But Your App Is Just Slow Because You're Lazy