문제

MSDN은 16 바이트 이하의 클래스가 구조물로 더 잘 처리 될 것이라고 말합니다. 소환.
왜 그런 겁니까?
구조물이 16 바이트 이상이면 클래스보다 효율적이지 않거나 동일하다는 것을 의미합니까?
클래스가 16 바이트 미만인지 어떻게 결정합니까?
구조물이 클래스처럼 행동하는 것을 제한하는 것은 무엇입니까? (매개 변수가없는 생성자를 허용하지 않고)

도움이 되었습니까?

해결책

이 질문에 대한 몇 가지 다른 답변이 있으며, 약간 주관적이지만, 내가 생각할 수있는 몇 가지 이유는 다음과 같습니다.

  • 스트러크는 값 유형이며 클래스는 참조 유형입니다. 총 스토리지에 16 바이트를 사용하는 경우 각각에 대해 메모리 참조 (4-8 바이트)를 만들어야 할 가치가 없습니다.
  • 실제로 작은 물체가 있으면 객체에 대한 참조 대신 종종 IL 스택으로 밀 수 있습니다. Callee 측에서 메모리 단위를 제거하기 때문에 실제로 일부 코드가 속도가 높아질 수 있습니다.
  • IL의 클래스와 관련된 약간의 추가 "보풀"이 있으며, 데이터 구조가 매우 작 으면 어쨌든이 보풀 중 어느 것도 사용되지 않으므로 필요하지 않은 여분의 쓰레기 일뿐입니다.

그러나 구조물과 클래스의 가장 중요한 차이점은 스트러크가 값 유형이고 클래스는 참조 유형이라는 것입니다.

다른 팁

"효율적"에 의해, 그들은 아마도 클래스 나 구조물을 나타내는 데 걸리는 메모리의 양에 대해 이야기하고있을 것입니다.

32 비트 플랫폼에서 객체를 할당하려면 최소 16 바이트가 필요합니다. 64 비트 플랫폼에서 최소 객체 크기는 24 바이트입니다. 따라서 사용 된 메모리의 양에서 순전히보고 있다면 16 바이트 미만의 데이터를 포함하는 구조물은 해당 클래스보다 "더 나은"것입니다.

그러나 사용 된 기억의 양은 전체 이야기가 아닙니다. 값 유형 (Structs)은 참조 유형 (클래스)과 근본적으로 다릅니다. 스트러크는 작업하기에 불편할 수 있으며주의하지 않으면 실제로 성능 문제를 일으킬 수 있습니다.

물론 진정한 대답은 상황에서 가장 잘 작동하는 것을 사용하는 것입니다. 대부분의 경우 수업을 사용하는 것이 훨씬 나아질 것입니다.

이 링크를 확인하고 오늘 답변 중 하나를 찾았습니다. .NET 유형 내부. 또한 structs와 클래스의 차이점에 대해 "참조 유형 대 가치 유형"에 대한 검색 및 인터넷 검색을 시도 할 수도 있습니다.

구조물이 클래스처럼 행동하는 것을 제한하는 것은 무엇입니까?

많은 차이점이 있습니다. 예를 들어 구조물에서 물려받을 수 없습니다.

가상 메소드가 없으므로 구조물을 사용하여 인터페이스를 구현할 수 없습니다. Structs의 인스턴스 방법은 Struct의 개인 필드에 액세스 할 수 있지만, 그 외에도 보조 "도우미"기능과 매우 흡사합니다 (불변의 스트러크의 경우 때로는 개인 데이터에 액세스 할 필요조차 없습니다). 그래서 나는 그들이 클래스 방법만큼 "귀중한"만큼 가까이 있지 않다는 것을 알았습니다.

이것은 CLR이 스트러크와 클래스를 처리하는 방식이 다르기 때문입니다. 스트러크는 값 유형으로 관리 된 힙이 아닌 스택에 살고 있음을 의미합니다. 일단 메소드 인수로 전달하기 시작하기 때문에 structs를 작게 유지하는 것은 좋은 경험 법칙입니다. 왜냐하면 방법 인수로 전달 될 때 structs가 전체적으로 복사 될 때 오버 헤드가 발생할 수 있기 때문입니다.

클래스는 메소드 인수로 사용될 때 메소드에 대한 참조 사본을 전달하기 때문에 메소드 인수로 사용될 때 훨씬 적은 오버 헤드가 발생합니다.

클래스의 크기를 결정하는 가장 좋은 방법은 클래스의 모든 멤버가 요구하는 바이트 수와 CLR 오버 헤드 항목에 대한 추가 8 바이트 (동기화 블록 색인 및 객체 유형에 대한 참조)를 총 8 바이트 수를 합치는 것입니다.

스트러크는 스택에 저장되며 힙에없는 클래스와 다릅니다. 즉, 구조물로 메소드를 매개 변수로 호출 할 때마다 사본이 생성되어 메소드로 전달됩니다. 그렇기 때문에 큰 구조가 매우 비효율적입니다.

그럼에도 불구하고 스트러크를 사용하는 것을 적극적으로 낙담시킬 것입니다. 그럼에도 불구하고 미묘한 버그를 유발할 수 있기 때문에, 예 : 구조물 필드를 변경할 때는 발신자에게 반영되지 않을 것입니다 (사본 만 변경했기 때문에) - 완전히 다른 동작입니다. 수업에.

따라서 내가 생각하는 16 바이트는 구조물의 합리적인 최대 크기라고 생각하지만 대부분의 경우 여전히 클래스를 갖는 것이 좋습니다. 여전히 구조물을 만들고 싶다면 적어도 구조물을 불변으로 만들어보십시오.

메모리에서 구조물은 데이터를 직접 보유하고 클래스는 포인터처럼 행동합니다. 그 자체만으로는 구조물을 매개 변수로 전달하면 메소드에 구조물을 전달하면 값을 전달하면 (스택에 복사) 클래스는 값에 대한 참조를 전달합니다. 구조물이 크면 각 메소드 호출에 많은 값을 복사하게됩니다. 그것이 실제로 작은 값을 복사하고 값을 직접 사용하는 것은 포인터를 복사하고 다른 곳에서 가져와야하는 것보다 더 빠를 것입니다.

제한 사항에 대해 : NULL에 할당 할 수는 없지만 (Nullable <>를 사용할 수는 있지만) 즉시 초기화해야합니다.

구조물 인스턴스를 복사하는 데는 클래스의 새 인스턴스를 작성하고 이전 클래스에서 데이터를 복사하는 것보다 시간이 줄어들지 만 클래스 인스턴스는 공유 할 수 있으며 구조 인스턴스는 할 수 없습니다. 따라서, "structvar1 = structvar2"는 새로운 구조물 인스턴스를 복사 해야하는 반면 "classVar1 = classVar2"는 classVar1을 허용하고 classVar2는 동일한 구조 인스턴스를 참조합니다 (새 제품을 만들 필요없이).

새로운 struct 인스턴스의 생성을 처리하기위한 코드는 최대 16 바이트의 크기에 최적화되어 있습니다. 더 큰 스트러크는 덜 효율적으로 처리됩니다. 구조물을 보유하는 모든 변수가 독립적 인 인스턴스를 보유하는 경우 Structs는 승리입니다 (즉, 특정 두 변수가 동일한 인스턴스를 보유 할 것으로 예상 할 이유가 없습니다). 많은 변수가 동일한 인스턴스를 보유 할 수있는 경우에는 많은 승리가 아닙니다 (전혀 승리하는 경우).

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