- 함수 내부의 if 문을 호출부로 올리면 코드의 복잡성 감소에 도움을 줌
-
조건 검사 및 분기 처리를 한 곳에서 집중하면 중복 및 불필요한 분기 확인을 쉽게 할 수 있음
-
enum 분해 리팩토링을 사용해 동일한 조건이 코드 곳곳에 퍼지는 문제를 방지할 수 있음
-
배치 연산 기반의 for문은 성능 향상과 반복 작업 최적화에 효과적임
-
if는 위로, for는 아래로 내리는 패턴을 조합해 코드 가독성과 효율성을 동시에 증대시킬 수 있음
두 가지 관련 규칙에 대한 간단한 메모
- 함수 내에 if 조건문이 존재할 경우, 이를 함수 호출부로 옮길 수 있는지 고민하는 방식이 추천됨
- 예시처럼, 함수 내부에서 precondition(전제 조건)을 검사하는 것보다, 호출부에 해당 조건 검사를 맡기거나 타입(혹은 assert)로 전제 조건을 보장하도록 만드는 것이 바람직함
- 전제 조건 검사를 위로 올리는(Push up) 방식은 코드 전반에 영향을 미쳐, 전체적으로 불필요한 조건 검사 수를 줄임 효과를 줌
제어 흐름과 조건문의 집중
-
제어 흐름과 if 문은 코드의 복잡성 및 버그의 주요 원인임
- 조건문을 호출부 등 상위로 집중시켜 분기 처리를 한 함수에만 몰아주고, 실제 작업은 직선적(스트레이트라인) 서브루틴에 맡기는 패턴이 유익함
- 분기와 제어 흐름이 한 곳에 모이면 중복 분기와 불필요한 조건을 쉽게 파악할 수 있음
예시:
- f 함수 내에 중첩된 if가 있을 때에는 죽은 코드(Dead Branch)를 인식하기 쉬움
- 여러 함수(g, h)를 통한 분기가 분산되면 이런 파악이 어려워짐
enum 분해 리팩토링(Dissolving enum Refactor)
- 코드가 같은 조건문 분기를 enum 등으로 내포하고 있을 경우, 조건을 상위로 끌어올려 분기와 작업을 더 명확하게 구분할 수 있음
- 이 방식을 적용하면, 동일한 조건이 코드에 여러 번 반복되어 나타나는 문제를 막을 수 있음
예시:
- 동일한 분기 조건이 f, g 함수와 enum E에 각각 표현된 상황을
- 하나의 상위 조건 분기로 코드 전체를 단순화할 수 있음
데이터 중심적 사고(Data Oriented Thinking)와 배치 연산
- 대부분의 프로그램은 여러 객체(엔티티)로 동작함. 크리티컬 경로(Hot Path)는 다수 객체 처리로 성능이 결정됨
- 배치(batch) 개념을 도입해서 객체 집합에 대한 연산을 기본으로 만들고, 단일 객체 연산은 특수 케이스로 처리하는 것이 바람직함
예시:
-
frobnicate_batch(walruses) 처럼 배치 처리 함수를 기본으로 두고,
-
개별 객체는 for 루프를 통해 처리하는 특수 케이스로 변환 가능함
-
이 방식은 성능 최적화 측면에서 중요한 역할을 하며, 대량 작업에서는 스타트업 비용을 감소시키고 순서 유연성을 높여줌
-
SIMD 연산(struct-of-array 등) 활용도 가능해, 특정 필드만 일괄 처리 후 전체 작업을 진행할 수 있음
실용적 사례와 추천 패턴
- FFT 기반 다항식 곱셈처럼, 여러 지점에서의 동시에 연산을 가능하게 만들어 성능 극대화가 가능함
- 조건문을 위로, 반복문을 아래로 내리는 규칙은 병행 적용 가능함
예시:
- 반복문 내부에서 같은 조건식을 계속 검사하는 것보다, 조건문을 반복문 바깥으로 빼면 반복 루프 내 분기를 줄이고 최적화 및 벡터화가 쉬워짐
- 이 접근법은 TigerBeetle 설계 등, 대규모 시스템 데이터 플레인에서도 높은 효율성을 보장함
결론
- if문(조건문)은 상위(호출부, 제어부) 로, for문(반복문)은 하위(연산부, 데이터 처리부) 로 내리는 패턴을 조합함으로써, 코드 가독성과 효율성, 성능 모두를 향상시킬 수 있음
- 추상 벡터 공간 시점으로의 사고(집합 단위 연산)는 반복적 분기 처리보다 더 좋은 문제 해결 도구임
- 요약하면, if는 위로, for는 아래로!