알고리즘 복잡성을 테스트해야합니까? 그렇다면 어떻게?


14

정렬 된 목록 / 배열 검색과 같은 간단한 것을 구현한다고 가정 해 봅시다. 함수 (c #)는 다음과 유사합니다.

static int FindIndex(int[] sortedList, int i);

나는 기능면에서 이것을 구현하고 테스트 할 수 있지만 명백한 이유로 나는 일반적으로 선형 검색이나 의도적으로 어리석은 것보다 이진 검색을 선호합니다.

내 질문은 : 알고리즘 복잡성 측면에서 성능을 보장하는 테스트를 작성해야합니까? 그렇다면 어떻게해야합니까?

나는이 질문의 "반드시해야 할 것"부분의 양쪽에서 논쟁을 시작했습니다. 그러나 나는 사람들이 내 주장없이 말한 것을 말하고 싶은 것을보고 싶습니다.

"어떻게"의 관점에서, 그것은 매우 흥미로워집니다 :) 비교 연산자를 매개 변수화하고 비교 연산자가 비교 또는 그와 유사한 것을 계산하는 테스트를받는 것을 볼 수 있습니다. 하지만 당신이해야한다는 의미는 아닙니다.

다른 사람이 (아마도) 이것을 고려 했습니까? 감사.


@ steenhulthin-- 여기서 끓 이도록하겠습니다. 나는 거기에가 본 적이 없다.
SirPentor

좋은 질문입니다. +1
Rafael Colucci

답변:


13

알고리즘 복잡도는 이론적 인 구성이므로 연필과 종이로 "테스트 된"것이 가장 좋습니다. 기계적으로는 유용하게 테스트 할 수 없습니다.

절대 성능 기계적으로 테스트 할 수 있으며 유용한 단위 테스트를 수행 할 수 있습니다. 성능이 중요한 경우 임계 값을 지정할 수 있습니다. "이 쿼리는 10 6 숫자에서 실행하는 데 50ms를 넘지 않아야 하고 10 7 숫자 에서 60ms를 넘지 않아야 합니다." 단위 테스트를 빌드 할 수 있습니다 .

최종 사용자는 알고리즘이 선형인지 로그인 지 상관하지 않습니다. 그들은 앱에 1 년 분량의 데이터가 있어도 UI가 여전히 즉각적으로 반응하는지 여부를 걱정합니다.


이것은 또한 본능입니다. 그러나 내가 생각한 것은 성능이 프레임 워크에서 보장 될 때입니다. 예 : 내가 올바르게 기억한다면 stl에는 알고리즘 복잡성에 대한 보증이 있습니다 (여기서는 생략 될 수 있습니다).
SirPentor

라이브러리가 일부 보증을 제공한다고해서 반드시 단위 테스트가 가능해야하는 것은 아닙니다.
svick

@Tobias Brick : 무언가를 테스트하고 정의하는 것은 서로 다른 두 가지입니다.
DeadMG

성능을 입증하는 것은 어렵습니다. 다양한 매개 변수에 대한 많은 샘플 포인트가 포함됩니다. 개별 기능이 사소한 경우에는 더 쉽지만 그 이상입니다 ... 부하, RAM, 프론트 버스 속도, CPU, 코어 수, 컴파일러 공격성, 레지스트리 오염 정도는 모두 특정 런타임에 영향을 미칩니다. 견본.
Job

3

이 도구가 단위 테스트에 특히 유용한 지 확실하지 않지만 Goldsmith, Aiken 및 Wilkerson의 " 실제 계산 복잡성"(Empirical Computational Complexity) 백서 에서는 코드를 계측하고 다양한 입력 세트에서 동적 동작을 경험적으로 관찰하는 방법을 설명합니다. 점근 적 복잡성을 유도하십시오. 이 백서에 설명 된 프로그램은 공개 소스이며 여기에서 사용할 수 있습니다 .

도움이 되었기를 바랍니다!


0

중요한 것은 빅 데이터로 시도하고 너무 오래 걸리는지 확인하는 것입니다.

이 예제 에서와 같이 성능 조정 경험에서 일부 알고리즘이 (예를 들어) O (n ^ 2)이면 발생하는 시간의 백분율이 레이더에 도달하지 않는 한 괜찮을 수 있습니다.

그러나 보이지 않지만 1 년에 한 번 크기의 데이터 세트가 제공되면 해당 알고리즘에 의해 흡수 된 총 시간의 일부가 치명적으로 지배적 일 수 있습니다.

테스트에서 그렇게 할 수 있다면 실제로 무한 루프처럼 문제를 찾는 것이 매우 쉽기 때문에 매우 좋습니다.


0

나는 당신이하고 싶은 것이 단위 테스트라고 생각하지 않습니다.

AFAIK, 단위 테스트는 코드가 수행해야 할 작업을 수행하고 성능에 중점을 두지 않도록하기위한 것입니다.

에서 위키 백과 : 테스트 프로그램의 모든 오류를 잡을 것으로 예상 할 수 없습니다 모두의 모든 실행 경로하지만 대부분의 사소한 프로그램을 평가하는 것은 불가능합니다. 단위 테스트에서도 마찬가지입니다. 또한 정의에 의한 단위 테스트는 단위 자체의 기능 만 테스트합니다. 따라서 통합 오류나 더 넓은 시스템 수준 오류 (예 : 여러 장치에서 수행되는 기능 또는 성능과 같은 비 기능 테스트 영역)는 포착하지 않습니다. 단위 테스트는 다른 소프트웨어 테스트 활동과 함께 수행해야합니다. 모든 형태의 소프트웨어 테스트와 마찬가지로 단위 테스트는 오류의 존재 만 보여줄 수 있습니다. 오류가 없음을 보여줄 수 없습니다.

성능을 측정하기위한 다른 종류의 도구와 패턴이 있습니다. 내가 지금 기억할 수있는 것 중 하나는 비 기능적 요구 사항에 중점을 둔 수락 테스트 입니다.

성능 테스트 (스트레스 테스트,로드 테스트 등을 사용) 와 같은 다른 것들은 거의 없습니다 .

또한 배포 단계 (즉, 내가하는 일)의 일부로 일부 스트레스 도구를 빌드 도구 (개미, 자동 빌드 스튜디오)와 함께 사용할 수 있습니다.

따라서 짧은 대답은 아니오입니다. 코드를 단위 테스트 할 때 걱정할 필요가 없습니다.


0

비교기를 전달하고 호출 횟수를 추적하면 고정 입력 (예 :)에서 검색을 수행 할 때 비교 횟수가 new int[] { 1,2,3, ... , 1024 }10 미만으로 유지 되는지 확인하는 등 간단한 목적으로 작동 합니다. 알고리즘의 작동 방식에 대한 의도를 분명히하십시오.

알고리즘이 O (log n)인지 확인하기 위해 단위 테스트가 올바른 방법이라고 생각하지 않습니다. 많은 랜덤 데이터 생성, 일부 커브 피팅 및 아마도 많은 데이터 포인트가 예상 런타임에 맞는지 여부를 결정하기 위해 심한 통계가 필요합니다. (이 알고리즘의 경우 아마도 가능하지만 정렬을 시작하면 최악의 시나리오를 반복해서 누르기가 어려워집니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.