문제

저는 깊이가 20년대 어딘가에 있는 나무 개체 세트를 가지고 있습니다.이 트리의 각 노드는 해당 트리의 루트에 액세스해야 합니다.

몇 가지 솔루션:

  1. 각 노드는 루트에 대한 참조를 직접 저장할 수 있습니다(메모리 낭비).
    • 런타임에 "상승"(폐기물 사이클)하여 근을 계산할 수 있습니다.
    • 정적 필드를 사용할 수 있습니다(그러나 이는 전역 필드에 해당합니다).

전역(어떤 변형이든)을 사용하지 않지만 메모리나 사이클 모두에서 #1이나 #2보다 더 효율적인 디자인을 누군가 제공할 수 있습니까?

편집하다: 나무 세트가 있기 때문에 나무를 구별하기 어렵기 때문에 단순히 정적으로 저장할 수는 없습니다.(maccullt에게 감사드립니다)

도움이 되었습니까?

해결책

루트를 필요한 노드의 함수에 매개변수로 전달합니다.

편집하다:옵션은 실제로 다음과 같습니다.

  1. 노드에 루트 참조를 저장합니다.
  2. 루트 참조를 전혀 저장하지 마십시오
  3. 루트 참조를 전역에 저장
  4. 스택에 루트 참조를 저장합니다(내 제안, 방문자 패턴 또는 재귀).

나는 이것이 모든 가능성이라고 생각하며 옵션 5는 없습니다.

다른 팁

왜 글로벌을 없애야 할까요?나는 전역이 나쁘다는 오명을 이해하지만 때로는 모든 요소가 포함된 전역 데이터 구조를 갖는 것이 가장 빠른 솔루션입니다.

당신은 절충안을 만듭니다:코드 명확성과 향후 성능 문제 감소.'아직 최적화하지 마세요'라는 의미입니다.최적화 단계에 있기 때문에 때로는 성능을 위해 가독성과 좋은 프로그래밍 방식을 생략해야 하는 경우도 있습니다.내 말은, 비트 해킹은 읽을 수 없지만 빠르다는 것입니다.

얼마나 많은 나무 개체가 있는지 잘 모르겠지만 개인적으로는 옵션 1을 사용하고 싶습니다.수천 개가 넘는 나무를 다루지 않는 한 포인터는 실제로 몇 개의 문자열보다 훨씬 더 많은 양이 되지 않습니다.메모리가 정말 중요한 문제라면 두 가지 방법을 모두 시도해 보고(구현하기가 매우 간단해 보임) 프로파일러를 통해 실행해 보세요.아니면 우수한 것을 사용하십시오 프로세스 탐색기.

편집하다:제가 작업 중인 앱 중 하나에는 약 55,000개의 노드가 포함된 노드 트리가 있습니다.우리는 트리 구조를 구축하고 O(1) 조회를 위한 배열도 유지합니다.재귀적인 FindNodeByID 메서드를 사용할 때 얻은 O(m*n)보다 훨씬 좋습니다.

일반적으로 루트를 매개변수로 전달하는 것이 가장 좋습니다.트리를 탐색하기 위해 일종의 반복자를 사용하는 경우 대안은 거기에 루트에 대한 참조를 저장하는 것입니다.

포인트 #1은 조기 메모리 최적화입니다.#2는 조기 성능 최적화입니다.메모리 또는 CPU 병목 현상이 문제를 일으키는지 확인하기 위해 앱을 프로파일링해 보셨나요?그렇지 않다면 사용자에게 도움이 되지 않는 "최적화"를 위해 유지 관리가 용이한 디자인을 희생할 이유가 무엇입니까?

#2를 선택하는 것이 좋습니다.대신 계산할 수 있는 것을 저장할 때마다 수행하는 작업은 캐싱입니다.캐싱을 사용하는 것이 좋은 경우도 있지만 유지 관리가 골치 아픈 경우도 있습니다.(예를 들어, 부모를 변경하여 노드를 한 트리에서 다른 트리로 이동했지만 루트 필드도 업데이트하는 것을 잊어버린 경우 어떻게 될까요?) 꼭 필요하지 않다면 캐시하지 마세요.

TreeView에서 클래스를 파생시킨 다음 싱글톤 정적 속성을 추가할 수 있습니다.이렇게 하면 클래스의 단일 인스턴스를 참조하는 전역 필드를 효과적으로 추가할 수 있지만 해당 클래스로 네임스페이스 범위가 지정된다는 이점이 있습니다.

내부 클래스에 대한 혐오감을 무시하고 Tree 클래스를 정의하고 노드를 내부 클래스로 정의할 수 있습니다.각 노드는 루트를 포함하여 트리의 상태에 액세스할 수 있습니다.

이는 Java가 노드를 상위 노드와 연결하는 방식에 따라 #1과 동일하게 될 수 있습니다.(잘 모르겠으니 프로필을 작성해야겠습니다)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top