
O(n*(n-1)) 또는 단순히 O(n^2) 시간이 걸린다는 것입니다. 즉, 엔티티의 수가 두 배가 될 때마다 모든 엔티티 간의 충돌을 감지하는 데 필요한 반복 횟수는 4배 더 커집니다. 3개의 엔티티의 경우 대략 9번의 반복이 필요하고, 30개 엔티티의 경우 900번, 300개 엔티티의 경우 90,000번 등입니다. 단일 확인이 상대적으로 저렴한 작업이고 화면에 많은 엔티티가 없다면 이 접근 방식을 사용해도 괜찮지만, 때로는 그렇지 않은 경우도 있습니다.
List 데이터 구조, 정확히는 단일 연결 리스트(singly linked list)를 구축할 것입니다. 리스트는 Lisp 프로그래밍 언어의 초기부터 알려진 함수형 프로그래밍의 기본 데이터 구조입니다. Haskell의 List 데이터 타입 선언을 살펴봅시다.Nil(빈 리스트) 또는 Cons(구성)로 값과 다른 리스트입니다. 리스트의 다음 값으로 다른 리스트를 가지는 것이 이 데이터 구조를 재귀적으로 만들거나 자신의 관점에서 정의하게 합니다. 리스트의 마지막 값은 항상 Nil이며, 리스트의 끝에 도달했음을 나타내는 데 사용됩니다. Nil은 또한 빈 리스트로 취급되므로 이 타입은 리스트의 속성을 상속합니다. 더 나은 이해를 위해 3개 항목의 리스트가 의사 코드로 어떻게 작성될 수 있는지 보여드립니다:Nil이 있는 3개의 cons 셀 체인입니다. 이는 다음과 같이 시각화할 수도 있습니다:
List, Cons, Nil입니다. List 타입은 리스트를 구축하는 데 정말 필요하지 않습니다. 왜냐하면 리스트는 단지 끝에 Nil이 있는 cons 셀의 체인이기 때문입니다. 오히려 리스트를 생성하고 조작하기 위한 API를 제공할 수 있는 유용한 추상화입니다.Nil 타입을 JavaScript 클래스로 구현하고 클래스의 인스턴스인 nil 변수를 생성하여 리스트의 끝 마커로 사용합니다.Cons입니다. 이는 head 값과 tail — 다음 값에 대한 참조를 받는 클래스입니다. 우리는 또한 new 키워드 사용을 피하기 위해 헬퍼 정적 메서드 .of를 만듭니다.Cons 위에 구축된 리스트 추상화는 리스트를 생성하고 조작하기 위한 API를 제공하여 시간과 코드를 절약할 수 있습니다. 따라서 Cons 위에 List 타입을 구축해봅시다:.fromValues 헬퍼를 구현합니다. 이것이 재귀적으로 리스트를 구축하는 방법에 주목하세요.List 클래스 정의에 새로운 정적 메서드를 추가합니다:take 메서드는 리스트에서 임의의 수의 값을 가져오는 데 사용됩니다.range와 take를 사용한 빠른 테스트add와 map 메서드입니다.add 작업은 매우 저렴합니다. 왜냐하면 리스트는 head에 효율적인 추가를 지원하기 때문입니다. head 위치에 값이 있는 새 리스트를 만들고 tail 위치에 대상 리스트를 만들면 됩니다:map 작업도 head 위치의 값이 재귀적으로 매퍼 함수에 적용되는 새 리스트를 반환합니다:filter와 reduce 같은 작업도 map과 유사하게 구현할 수 있습니다.List 데이터 구조와 그 재귀적 구현에 대해 배웠습니다. 유사한 추론을 앞서 언급한 quadtree와 다른 모든 데이터 구조를 구축하는 데 적용할 수 있습니다. 나중에 여기서 List의 lazy 버전을 만들 것입니다.List의 lazy 버전을 구현하기 전에 lazy evaluation이 무엇인지 빠르게 상기해봅시다..run 메서드 호출까지 실행되지 않습니다. 물론 nothing happened는 완전히 사실이 아닙니다. 호출될 때마다 작업이 나중에 실행되도록 저장되고 결과가 요청되면 전체 체인이 실행되고 최종 값이 반환됩니다. Haskell과 Clojure 같은 언어는 지연된 실행에 크게 의존합니다. Haskell에서는 예를 들어 모든 것이 thunk에 저장됩니다. thunk를 평가를 방지하는 임의의 코드에 대한 컨테이너로 생각할 수 있습니다. 식을 포함하는 클로저일 수 있습니다. Eager 버전의 1 + 1은 JavaScript에서 lazy () => 1 + 1로 표현될 수 있습니다. 예를 들어 숫자를 더하고 빼는 lazy 함수를 만들어봅시다:add와 sub 모두 인수를 닫은 함수를 반환하므로 실제 작업은 아직 실행되지 않으며, 반환된 thunk를 호출하여 강제할 때까지 실행되지 않습니다.Cons 타입 위에 구축할 LazyList 추상화의 초기 구현입니다.fn은 cons 셀을 반환해야 하는 thunk이고 next 메서드는 thunk를 평가합니다..fromValues 헬퍼가 어떻게 리스트를 lazy하고 재귀적으로 구축하는지 보세요. 이는 인수의 값이 있는 head와 다른 lazy 리스트인 tail을 가진 Cons의 thunk를 포함하는 LazyList의 인스턴스를 반환합니다.take도 lazy 리스트를 반환합니다. 하지만 실제 값을 가져오기 위해 thunk를 하나씩 평가하고 대상 리스트의 tail에서 가져온 후 새로운 것을 구성합니다.range는 값의 범위를 반환하는데, 이제 laziness를 사용하면 무한 리스트를 만들 수 있습니다.List 구현과 매우 유사합니다.map 작업도 eager 버전과 유사합니다..toString. 일반적인 JavaScript 시설을 사용하여 리스트를 사용할 수 있으려면 의미 있는 것으로 변환되어야 합니다. 예를 들어 배열입니다. .toArray 메서드는 정확히 이것을 합니다..next 메서드를 호출할 때마다 thunk를 평가하고 결과를 메모이제이션하거나 이미 캐시된 경우 결과를 반환합니다. LazyList 클래스에 필요한 수정 사항은 다음과 같습니다:getUsers 함수는 thunk가 평가될 때 요청 시 데이터베이스에서 사용자 레코드를 가져와 리스트를 lazy하게 생성합니다.users 리스트가 첫 번째 실행에서 평가되었고 결과가 후속 호출을 위해 메모이제이션되었기 때문입니다.아직 댓글이 없습니다.
첫 번째 댓글을 작성해보세요!
[번역] Async Hooks (비동기 훅)
n-ryu • Back-End
[번역] JavaScript에서 "undefined"를 확인하는 가장 적절한 방법은 무엇인가요?
n-ryu • Front-End
[번역] 좋은 질문을 하는 방법은 무엇인가요? - 고객 센터
n-ryu • Career
![[번역] 내가 어떻게 여기까지 왔을까?](https://how-did-i-get-here.net/banner.png)
[번역] 내가 어떻게 여기까지 왔을까?
n-ryu • Computer Science