if는 위로, for는 아래로: 관용 패턴과 그 대수, 그리고 한계

1 hour ago 3

조건 분기는 호출자에, 반복문은 배치 처리 함수 내부에 배치하면 제어 흐름을 중앙화하고 핵심 처리 로직을 단순화할 수 있음 호출자가 None을 처리하고 함수가 Option<Walrus> 대신 Walrus를 받게 하면, 입력 타입이 사전 조건을 드러내며 내부에서 고려할 상태가 줄어듦 데이터베이스의 선택/투영 조기 실행과 벡터화 실행도 유사한 구조를 가짐: 조인 입력을 줄이고, 행마다 지불하던 호출 비용을 배치 단위로 나눔 filter를 map 앞으로 옮길 때는 술어도 함께 변환해야 하며, 실제 계산 절감은 변환된 술어 p. f를 저렴한 입력 술어로 단순화할 수 있을 때 가능함 대수적 법칙과 적용 조건이 변환의 정당성을 결정함: 루프 불변 조건만 반복문 밖으로 꺼낼 수 있으며, 반복을 배치 함수 안으로 옮기는 일은 동치성보다 비용 구조에 초점이 있음 조건은 호출자에, 반복은 배치 함수 안에 TigerBeetle의 Tiger Style은 큰 함수를 분리할 때 제어 흐름을 부모 함수에 중앙화하고, 분기가 없는 로직을 보조 함수로 옮기도록 권장함 부모 함수가 switch/if를 담당하고 나머지 함수는 제어 흐름을 신경 쓰지 않도록 책임을 나눔 matklad의 글에서 조건을 위로 올리는 예는 frobnicate(walrus: Option<Walrus>)의 None 처리를 호출자로 이동하는 것임 핵심 함수는 일반 Walrus만 받으므로 타입이 사전 조건을 명시하고 입력 상태 공간이 좁아짐 핵심은 하류로 흐르는 데이터의 양이 아니라 판단을 어디에서 수행하느냐에 있음 반복을 아래로 내리는 방식은 호출자가 frobnicate(walrus)를 반복 호출하는 대신 frobnicate_batch(walruses) 를 호출하고, 그 안에 반복문을 두는 것임 필터링이나 데이터 축소 이후 반복을 수행하면 불필요한 계산을 줄일 수 있음 핵심 반복문에서 분기를 없애면 벡터화의 후보가 됨 두 변환을 결합하면 호출자가 Vec<Option<Walrus>>에서 None을 버리고 값을 꺼내 Vec<Walrus> 를 만든 뒤 배치 함수에 전달함 into_iter().filter_map(|w| w).collect()로 입력을 정리하면 frobnicate_batch(&walruses)는 None을 고려할 필요가 없음 데이터베이스: 선택/투영은 일찍, 조인은 나중에 쿼리 최적화에서도 선택과 투영을 ...

Read Entire Article