코드를 작성할 때 항상 코드를 최대한 깨끗하고 읽기 쉽게 작성하려고합니다.
때때로 당신은 줄을 넘고 더 깨끗한 코드에서 더 추악한 코드로 이동해야 할 때가옵니다.
언제 그 선을 넘어도 괜찮습니까?
코드를 작성할 때 항상 코드를 최대한 깨끗하고 읽기 쉽게 작성하려고합니다.
때때로 당신은 줄을 넘고 더 깨끗한 코드에서 더 추악한 코드로 이동해야 할 때가옵니다.
언제 그 선을 넘어도 괜찮습니까?
답변:
당신은 때 선을 넘어
실제 예제는 다음과 같습니다. 실행중인 실험 시스템이 데이터를 너무 느리게 생성하여 실행 당 9 시간 이상 걸리고 CPU의 40 % 만 사용했습니다. 코드를 너무 많이 엉망으로 만드는 대신 모든 임시 파일을 메모리 내 파일 시스템으로 옮겼습니다. 추악하지 않은 코드의 8 줄을 추가했으며 이제 CPU 사용률이 98 % 이상입니다. 문제 해결됨; 추한 필요가 없습니다.
foo
하고 이름을 바꿉니다. foo_ref
일반적으로 foo
소스 파일에서 바로 위에 있습니다. 내 테스트 장치에서 나는 전화 foo
및 foo_ref
검증과 상대 성능 측정합니다.
거짓 이분법입니다. 당신은 코드를 빠르게 만들 수 있습니다 및 유지 관리가 용이.
당신이하는 방법은 특히 가능한 한 간단한 데이터 구조로 깨끗하게 작성하는 것입니다.
그런 다음 타임 드레인의 위치를 알고 ( 이전에 작성한 후 , 이전이 아니라 실행하여 ) 하나씩 수정하십시오. (여기에 예가 있습니다.)
추가 : 우리는 항상 시간과 메모리 사이의 균형 또는 속도와 유지 보수성 간의 균형과 같은 균형에 대해 듣고 있습니까? 그러한 곡선이 존재할 수도 있지만, 주어진 프로그램이 곡선 위에 있거나 심지어 그 근처 에 있다고 가정해서는 안됩니다 .
곡선에있는 모든 프로그램은 (특정 종류의 프로그래머에게 제공함으로써) 훨씬 느리게 유지되고 유지 보수가 용이하지 않은 상태로 쉽게 만들어 질 수 있으며, 곡선 근처에는 아무 것도 없습니다. 그런 프로그램에는 더 빠르고 유지 보수가 용이 한 공간이 충분합니다.
내 경험상 많은 프로그램이 시작됩니다.
내 OSS 존재에서 나는 성능을 겨냥한 많은 라이브러리 작업을 수행합니다. 이것은 발신자의 데이터 구조 (즉, 라이브러리 외부)와 밀접하게 관련되어 있으며 , 의도적으로 들어오는 유형에 대한 의무는 없습니다. 이 성능을 발휘할 수있는 가장 좋은 방법 은 메타 프로그래밍입니다. .NET-land에 있으므로 IL-emit을 의미합니다. 그것은 추악하고 못생긴 코드이지만 매우 빠릅니다.
이런 식으로, 나는 라이브러리 코드가 애플리케이션 코드 보다 "더 추악하다"는 것을 행복하게 받아들이고 , 입력에 대한 제어가 적거나 전혀 없기 때문에 단순히 다른 메커니즘을 통해 일부 작업을 수행해야한다고 주장 한다. 또는 다른 날에 그것을 표현했을 때 :
"광기의 절벽을 코딩 하기 때문에 "
이제 응용 프로그램의 "일반"(제정신) 개발자는 일반적으로 자신의 협업 / 전문 많은 시간을 투자하는 곳이기 때문에 코드는 약간 다릅니다; 각각의 목표와 기대는 (IMO) 약간 다릅니다.
IMO, 답변은 위가 빨리 될 수 있습니다 제안 하고 참조하고 유지하기 위해 쉽게 응용 프로그램 개발자가 데이터 구조를보다 효율적으로 제어 할 수 있고, 메타 프로그래밍 같은 도구를 사용하지 않는 코드입니다. 즉, 다른 수준의 광기와 다른 수준의 오버 헤드로 메타 프로그래밍을 수행하는 다른 방법이 있습니다. 이 분야에서도 적절한 추상화 수준을 선택해야합니다. 그러나 적극적으로 긍정적으로 생각할 때, 예상치 못한 데이터 를 절대적으로 가장 빠르게 처리하기를 원할 때 ; 잘 못 생길 수도 있습니다. 그것으로 처리; p
코드를 프로파일 링하고 실제로 심각한 속도 저하를 일으키는 지 확인한 경우.
클린 코드는 반드시 빠른 실행 코드와 배타적 일 필요는 없습니다. 일반적으로 읽기 어려운 코드는 더 빨리 실행되기 때문이 아니라 쓰기가 더 빠르기 때문에 작성되었습니다.
변경 사항이 실제로 무엇을 개선하는지 확실하지 않기 때문에 더 빠른 시도를 위해 "더러운"코드를 작성하는 것은 논란의 여지가 없습니다. Knuth가 가장 잘 설명했습니다.
"우리는 시간의 97 % 정도의 작은 효율성을 잊어야한다. 조기 최적화는 모든 악의 근원이다 . 그러나 우리는 그 중요한 3 %의 기회를 포기해서는 안된다. 좋은 프로그래머는 그런 것에 의해 만족에 빠지지 않을 것이다. 이유는, 그는 중요한 코드에서주의 깊게 볼 것이 현명 할 것입니다,하지만 그 코드가 확인 된 후에 만 ".
다시 말해, 코드를 먼저 깨끗하게 작성하십시오. 그런 다음 결과 프로그램을 프로파일 링하고 해당 세그먼트가 실제로 성능 병목 현상인지 확인하십시오. 그렇다면 필요에 따라 섹션을 최적화하고 최적화를 설명하기 위해 많은 문서 주석 (원본 코드 포함)을 포함 시키십시오. 그런 다음 결과를 프로파일 링하여 실제로 개선했는지 확인하십시오.
질문에 "빠른 코드 를 읽기 어렵다 "는 말이 있기 때문에 간단한 대답은 결코 없습니다. 읽기 어려운 코드 작성에 대한 변명의 여지가 없습니다. 왜? 두 가지 이유가 있습니다.
폐기 코드 인 경우. 나는 그 말 그대로 : 당신이 일회성 계산이나 작업을 수행하고, 그러한 확신 할 수있는 스크립트를 작성할 때 당신은 'RM 소스 파일'주저없이 할 수있는 다시 조치를 할 필요가 없을 것이다 다음 당신이 선택할 수 있습니다 못생긴 길.
그렇지 않으면 잘못된 이분법입니다. 더 빨리하기 위해 못생긴다고 생각하면 잘못하고있는 것입니다. (또는 좋은 코드가 무엇인지에 대한 당신의 원칙은 수정해야합니다. goto를 사용하는 것이 문제에 대한 적절한 해결책 일 때 실제로 매우 우아합니다. 그러나 거의 그렇지 않습니다.)
나에게 그것은 안정성의 비율입니다 (콘크리트에서 시멘트로, 오븐에서 구운 점토, 영구적으로 잉크로 쓰여진 돌로 설정). 미래에 코드를 변경해야 할 확률이 높을수록 코드가 불안정할수록 습식 점토와 같이 생산성을 유지하기가 더 쉬워집니다. 또한 가독성이 아니라 유연성을 강조합니다. 나에게 코드 변경의 용이성은 코드를 읽는 것보다 중요합니다. 코드를 쉽게 읽을 수 있고 악몽을 바꿀 수 있으며, 악의적 인 변경 사항 인 경우 구현 세부 사항을 읽고 이해하기 위해 어떤 용도로 사용할 수 있습니까? 그것이 학술적인 연습이 아닌 한, 일반적으로 프로덕션 코드베이스에서 코드를 쉽게 이해할 수 있다는 점은 필요에 따라 코드를 더 쉽게 변경할 수 있도록하는 것입니다. 변경하기 어려운 경우 가독성의 많은 이점이 창 밖으로 나옵니다. 가독성은 일반적으로 유연성의 상황에서만 유용하며, 유연성은 불안정성의 상황에서만 유용합니다.
당연히 코드를 읽는 것이 얼마나 쉬운 지 또는 어려운지에 관계없이 상상할 수있는 코드를 유지하기가 가장 어려운 경우에도 변경할 이유가없는 경우 문제를 일으키지 않고 사용하십시오. 그리고 특히 성능이 가장 중요시되는 저수준 시스템 코드의 경우 이러한 품질을 달성 할 수 있습니다. 나는 아직도 정기적으로 사용하는 C 코드를 가지고 있으며 80 년대 후반부터 변경되지 않았습니다. 그 이후로 변경할 필요가 없었습니다. 이 코드는 엉뚱한 날에 작성되었으며, 나는 거의 이해하지 못합니다. 그러나 오늘날에도 여전히 적용 가능하며 많은 활용을 위해 구현을 이해할 필요가 없습니다.
철저하게 테스트를 작성하는 것이 안정성을 향상시키는 한 가지 방법입니다. 다른 하나는 디커플링입니다. 코드가 다른 것에 의존하지 않는다면 코드를 변경하는 유일한 이유는 코드 자체가 변경되어야하기 때문입니다. 때로는 소량의 코드 복제가 디커플링 메커니즘의 역할을하여 안정성을 획기적으로 향상시켜 다른 코드와 완전히 독립적 인 코드를 얻는 경우 가치있는 트레이드 오프가 될 수 있습니다. 이제 그 코드는 외부 세계의 변화에 무적입니다. 한편 10 개의 서로 다른 외부 라이브러리에 의존하는 코드는 앞으로 변경해야하는 10 배의 이유가 있습니다.
실제로 또 다른 유용한 것은 라이브러리를 코드베이스의 불안정한 부분과 분리하고, 제 3 자 라이브러리에서와 같이 개별 라이브러리를 빌드하는 것입니다 (적어도 아닙니다. 팀). 이러한 유형의 조직만으로도 사람들이 변조하지 못하게 할 수 있습니다.
또 다른 하나는 미니멀리즘입니다. 코드가 덜 노력할수록 코드가 잘 수행 할 수있는 가능성이 높아집니다. 모 놀리 식 디자인은 거의 영구적으로 불안정합니다. 점점 더 많은 기능이 추가 될수록 더 불완전 해 보입니다.
마이크로 튜닝 된 병렬 SIMD 코드와 같이 필연적으로 변경하기 어려운 코드를 작성하려고 할 때마다 안정성이 주요 목표가되어야합니다. 코드를 변경할 필요가 없기 때문에 코드를 유지 관리하는 데 어려움이 있으므로 향후 코드를 유지할 필요가 없습니다. 따라서 코드 유지 관리가 어려워도 유지 관리 비용이 0으로 줄어 듭니다.