문제

나는 현재 Scala와 함께 여가 시간에 기능적 프로그래밍을 배우고 있으며 유휴 초보자 질문이 있습니다.

Haar Wavelet Transform을 계산하는 것과 같은 일을 할 때 불변의 물체가있는 우아함을 볼 수 있습니다. 즉, 객체로 표시되는 데이터 자체가 변경되지 않을 때.

그러나 나는 불변성을 보여줄 때 누군가가 작은 게임을 한 블로그를 보았습니다. 생물 객체가 손상을 받으면 상태가 바뀌지 않았다. 새로운 히트 포인트와 새로운 "Aggro"플래그가있는 새로운 생물 객체를 반환했다. 그러나 우리가 MMORPG와 같은 것을 디자인한다면 World of Warcraft는 말합니다. 전장에있는 100 명의 선수들이 ... 아마도 수천 건의 공격과 버핑/디버 핑 주문 효과가 다른 방식으로 그들에게 영향을 미칩니다. 완전히 불변의 물체로 시스템을 설계 할 수 있습니까? 나에게 그것은 '진드기'가 각각 새로운 인스턴스의 거대한 무리가있는 것처럼 보일 것입니다. 그리고 현재 유효한 객체 인스턴스를 얻으려면 모든 클라이언트는 일종의 중앙 "Gameworld"객체 또는?

기능적 프로그래밍은 이에 대한 규모가 규모입니까?

도움이 되었습니까?

해결책

나에게 그것은 '진드기'가 각각 새로운 인스턴스의 거대한 무리가있는 것처럼 보일 것입니다.

실제로, 그 사실입니다. 저는 시장 데이터 피드 (6 시간 거래일 동안 약 5 백만 메시지, 우리가 관심있는 데이터에 대한 약 5 백만 메시지)를 읽는 Haskell 응용 프로그램이 있으며 다음과 같은 다양한 것들에 대한 "현재 상태"를 유지합니다. 가장 최근의 입찰 및 기기에 대한 가격 및 수량, 우리의 모델이 시장에 얼마나 잘 맞는지 등을 제공하는 등. 실행 중 처음 500 초 동안 메모리 (또는 기계의 RAM 크기의 5 만 배). (프로파일 링은 응용 프로그램을 늦출뿐만 아니라 하나의 코어에서도 실행되도록 강요하기 때문에 프로파일 링 없이는 수치가 상당히 높아질 것입니다.)

그러나 순수한 언어 구현의 쓰레기 수집가는 이러한 종류의 행동에 최적화되어 있습니다. 나는 내 애플리케이션의 전반적인 속도에 매우 만족하며, 시장 피드에서 초당 수백 개의 메시지를 구문 분석하고 모델을 구축하고 사용하기 위해 상당히 광범위한 계산을해야한다는 점에서 상당히 까다로울 것이라고 생각합니다. 모델을 최대한 빨리 교환으로 갈 주문을 생성합니다.

다른 팁

일반적으로 기능 프로그래밍에는 C ++ 스타일 생성자가 없습니다. 그런 다음 개념적으로 객체를 항상 생성하더라도 컴파일러가 프로그램의 동작에 영향을 줄 수 없기 때문에 새로운 객체를 할당하기 위해 코드를 만들어야한다는 의미는 아닙니다. 데이터는 불변이기 때문에 컴파일러는 방금 지정 한 값과 기능에 전달 된 내용을 볼 수 있습니다.

그런 다음 컴파일러입니다 ~할 수 있다 필요할 때 특정 객체의 필드를 계산하는 정말 타이트한 컴파일 코드를 만듭니다. 이 작동 방식은 사용하는 컴파일러의 품질에 달려 있습니다. 그러나 Clean Functional Programming Code는 유사한 프로그램의 C 컴파일러보다 코드에 대해 컴파일러에 상당히 더 많은 것을 알려줍니다. 따라서 좋은 컴파일러가 5월 기대하는 것보다 더 나은 코드를 생성하십시오.

따라서 적어도 이론적으로는 걱정할 이유가 없습니다. 기능적 프로그래밍 구현은 객체 지향 힙 할당 구현뿐만 아니라 확장 될 수 있습니다. 실제로, 당신은 당신이 함께 일하는 언어 구현의 품질을 이해해야합니다.

mmorpg입니다 이미 불변성의 예. 게임은 서버 및 게이머 시스템에 배포되므로 중앙 "Gameworld"객체는 전혀 없습니다. 따라서 와이어 위로 전송되는 객체는 불변이 불변입니다. 수신기에 의해 변경되지 않기 때문입니다. 대신, 새로운 객체 나 메시지가 있으면 응답으로 전송됩니다.

나는 분산 게임을 한 적이 없어서 그들이 어떻게 구현되는지 정확히 알지 못하지만 객체에 대한 업데이트가 로컬로 계산되거나 와이어 위로 Diffs로 전송 된 것으로 생각됩니다.

예를 들어, 당신은 Command & Conquer를 재생하고 있습니다. 매머드 탱크는 기지를 지키는 준비된 모드에 앉아 있습니다. 당신의 상대방은 당신의베이스를 탐험하기 위해 경전차로 접근합니다. 매머드 탱크가 상대방의 탱크를 쏘고 부딪쳐 손상을 입 힙니다.

이 게임은 매우 간단하므로 가능할 때마다 많은 부분이 로컬로 계산 된 것으로 생각됩니다. 두 플레이어의 컴퓨터가 처음에는 게임 상태 측면에서 동기화되어 있다고 가정합니다. 그런 다음 상대방이 클릭하여 경전차를베이스로 옮깁니다. 메시지 (불변)가 전선을 통해 전송됩니다. 탱크를 이동하려는 알고리즘은 (아마도) 결정 론적이므로 명령 및 정복 사본은 상대방의 탱크를 화면에서 이동하여 게임 상태를 업데이트 할 수 있습니다 (불변 또는 변이 가능). 경전차가 매머드 탱크의 범위에 들어가면 탱크가 발생합니다. 서버에서 임의의 값이 생성됩니다 (이 경우 하나의 컴퓨터는 서버로 임의로 선택됩니다). 탱크가 치고 상대방의 탱크에 대한 업데이트가 이루어져야한다고 가정하면, 탱크의 새로운 갑옷 수준이 22%로 감소했다는 사실은 두 플레이어의 게임을 동기화하기 위해 와이어 위로 전송됩니다. 이 메시지는 불변입니다.

탱크를 나타내는 선수의 컴퓨터의 물체가 변이 가능하든 불변인지 여부는 관련이 없습니다. 어느 쪽이든 구현할 수 있습니다. 각 플레이어는 다른 게이머 게임의 상태를 직접 변경하지 않습니다.

불변성에 주목해야 할 한 가지 점은 (올바르게 구현 된 경우) 객체 생성이 비교적 가볍게 만든다는 것입니다. 필드가 불변이라면 인스턴스간에 공유 할 수 있습니다.

기능 프로그램을 설계 할 때는 불변의 객체에 약간의 오버 헤드가있는 기능 프로그램을 설계 할 때 고려해야합니다. MMORPG 프로그램에 객체가 불변이되면 본질적으로 더 확장 가능하다는 것을 기억하는 것이 중요합니다. 따라서 장비에 대한 초기 투자는 더 높을 수 있지만 상황이 확장됨에 따라 플레이어 기반으로 확장 할 수 있습니다.

고려해야 할 또 다른 중요한 사항은 현재 가장 멍청한 기계에는 CPU 당 6 개의 코어가 있다는 것입니다. 각각 6 개의 코어가있는 듀얼 CPU 머신을 고려하십시오. 이 12 개의 코어 중 하나는 쓰레기 수집을 수행 할 수 있으므로 응용 프로그램이 다른 11 코어에 쉽게 확장 할 수 있으므로 많은 물체를 찢어 버릴 수 있습니다.

또한 모든 객체 (및 하위 객체)가 사본에 완전히 재건 될 필요는 없습니다. 변경되지 않은 참조 유형은 객체가 "복사"될 때만 단일 참조 할당 만 수행합니다.

와이어 레벨에서 객체 생성을 생각하지 마십시오. 예를 들어, 기능적 언어에 대한 최적화 된 런타임은 아마도 객체를 대체하고 기존 구조물의 실제 DO 돌연변이를 교체 할 때 "속임수"를 할 수있을 것입니다. 꼬리 재귀 최적화를 생각하지만 객체 상태에 적용됩니다.

오늘이 게시물에서 제기 한 질문을 정확히 다루는 블로그를 찾았습니다.

http://prog21.dadgum.com/23.html

프로그래밍의 거의 모든 도구와 마찬가지로 불변의 물체는 강력하지만 잘못된 상황에서는 위험합니다. 나는 게임 예제가 아주 좋은 것이 아니거나 적어도 매우 고려되지 않는다고 생각합니다.

Eric Lippert는 흥미로운 점이 있습니다 게시물 불변성에 관한 주제에 대해, 그들은 매우 흥미로운 독서입니다.

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