GN⁺: ifs 상승 및 fors 하락
(matklad.github.io)함수 내 조건문 상향 이동
- 함수 내
if
조건문이 있다면 호출자(caller)로 이동하는 것을 고려함. - 함수가 전제 조건을 내부에서 확인하고 조건이 충족되지 않으면 '아무 것도 하지 않는' 대신, 호출자가 전제 조건을 확인하도록 하여 타입을 통해 전제 조건이 충족됨을 보장함.
- 전제 조건을 특히 '상향 이동'하면 전반적으로 확인 작업이 줄어들 수 있으며, 이는 이 규칙의 동기 중 하나임.
반복문 하향 이동
- 데이터 지향적 사고에서 나온 규칙으로, 객체의 '배치(batch)' 개념을 도입하고 배치 작업을 기본 케이스로 삼으며, 스칼라 버전을 배치 버전의 특별한 경우로 취급함.
- 성능 향상이 주요 이점이며, 시작 비용을 분산시키고 처리 순서에 유연함을 가질 수 있음.
- 예를 들어, FFT 기반 다항식 곱셈은 여러 점에서 동시에 다항식을 평가하는 것이 개별 평가보다 빠를 수 있음.
GN⁺의 의견
- 이 글에서 가장 중요한 것은 소프트웨어 개발에서 성능과 코드의 명확성을 향상시키기 위한 두 가지 프로그래밍 규칙인 '조건문 상향 이동'과 '반복문 하향 이동'임.
- 이러한 규칙들은 코드의 가독성을 높이고, 성능을 최적화하며, 버그 발생 가능성을 줄이는 데 도움이 됨.
- 소프트웨어 엔지니어링의 복잡성을 관리하고 효율적인 코드를 작성하는 방법에 대한 통찰을 제공하기 때문에 이 글은 많은 개발자들에게 흥미롭고 유익함.
Hacker News 의견
- 데이터 지향 설계에 대한 조언에 대한 반발이 놀랍다는 의견이 있음. 대부분의 포럼 사용자들이 웹 애플리케이션을 작성하고 있어 이 조언이 무의미해 보일 수 있음. 일상 업무에서 명령어 캐시에 대해 생각할 필요가 없다면 이 조언을 무시해야 함. Mike Acton의 "Typical C++ Bullshit"을 참고하면 이 조언의 중요성을 이해할 수 있음.
- 프로그래머들이 코드를 "작은 단위"에서 예쁘게 만드는 데에는 신경을 쓰지만, 전체 코드베이스의 적절한 설계에는 충분히 신경 쓰지 않는다는 의견이 있음. 함수가 잘 명명되고, 좋은 인터페이스를 가지며, 명확한 목적을 가지고, 적절히 문서화되어 있고, 부작용을 과도하게 사용하지 않는다면, 함수가 지저분하거나 if와 for의 배치에 대해서는 크게 신경 쓰지 않아야 함.
- 과학 분야에서 프로그래밍을 시작한 사람으로부터, 작은 최적화가 중요하다는 의견이 있음. for 루프의 순서를 잘못 사용하면 시뮬레이션 실행 시간이 1주일에서 1시간으로 단축될 수 있음. 이러한 배경을 가진 사람은 for와 if의 순서를 본능적으로 최적화함.
- "컨테이너"가 있을 경우, 컨테이너에 대한 함수를 작성하기보다는 컨테이너가 담고 있는 도메인 수준의 "Thing"에 대한 함수를 작성해야 한다는 의견이 있음. 이는 코드를 더 유연하게 만들고, 핵심 도메인과 애플리케이션의 관심사를 더 명확하게 구분함.
- 함수의 전제 조건과 후속 조건을 함수 정의에서 직접 볼 수 없게 만드는 "if"의 상향 이동의 단점이 있음. 큰 프로젝트에서는 이러한 함수가 의도한 맥락 외부에서 재사용될 수 있으며, 버그를 초래할 수 있음. 계약 프레임워크를 사용하는 것이 하나의 해결책이 될 수 있지만, 계약과 코드에서 조건을 두 번 작성해야 함.
- Rust 언어를 사용한 예시에서, Rust의 강력한 타입 시스템이 다른 언어에서 필요한 방어적 프로그래밍을 방지함. C 프로그래머가 함수에 전달된 포인터의 유효성을 확인하지 않고 NULL 참조를 발생시키는 경우는 바람직하지 않음. 일부
if
는 함수 하단이 아닌 상단에 있어야 하며, 오류가 잘 전파되어야 함. - 기사가 특정 코드 예시로 이어질 것 같았지만 실제로는 그렇지 않았다는 의견이 있음. 예상된 코드 예시 대신 다른 예시를 제시함.
- 적절한 맥락 없이는 이 조언이 이상하고 심지어 나쁜 조언일 수 있음. for 루프와 if 문은 모두 제어 흐름 연산이므로, 기사의 일부 주장은 의미가 없어 보임. 성능에 관한 주장이 가장 강하지만, 일반적인 조언에 대한 우려사항으로는 마지막에 고려해야 함.
- 일반적인 규칙이 실제 코드에 적용될 수 있는지 확신할 수 없다는 의견이 있음. 이러한 규칙을 잘못된 도그마로 보는 경우가 많으며, 젊은 프로그래머들이 이를 잘못 받아들여 더 나쁜 코드를 작성할 수 있음. 조건이
walrus
에 의존하는 경우가 많기 때문에if
를 상향 이동시킬 수 없음. - 전제 조건
if
를 호출자로 올리는 것은 끔찍한 아이디어라는 의견이 있음. 특별한 경우에는 좋은 생각일 수 있지만, 일반적인 경우에는 이를 원하지 않음. 라이브러리에서는 외부 경계에서 전제 조건을 확인하여 내부 구현이 내부 가정 없이 진행될 수 있도록 해야 함. 호출자가 확인을 의존하는 것은 목적을 무효화함.