문제

일련의 숫자 데이터에 대해 작동하는 알고리즘을 작성하고 있습니다. 때로는 시리즈의 값이 무효가되어야합니다. 그러나이 응용 프로그램은 성능이 중요하기 때문에 무효 유형의 사용을 피했습니다. 나는 Nullable 유형과 nullable 유형을 사용하는 성능을 구체적으로 비교하기 위해 알고리즘을 테스트했으며, 최상의 시나리오 Nullable 유형은 2 배 느리지 만 종종 더 나쁩니다.

가장 자주 사용되는 데이터 유형은 두 배이며 현재 NULL에 대한 선택된 대안은 Double.nan입니다. 그러나 나는 이것이 NAN 가치에 대한 정확한 사용법이 아니라는 것을 이해하므로, 이것에 문제가있을 수 없는지, 그리고 모범 사례가 무엇인지 확실하지 않습니다.

특히 Double/Float, Decimal, DateTime, Int/Long (다른 사람들은 환영하는 것 이상)에 대한 최고의 Null 대안이 무엇인지 알아 내고 싶습니다.

편집 : 성능에 대한 요구 사항을 명확히해야한다고 생각합니다. 수치 데이터의 공연은 몇 시간이 걸리는 한 번에 이러한 알고리즘을 통해 처리됩니다. 따라서 EG 10ms 또는 20ms의 차이는 일반적으로 중요하지 않지만,이 시나리오에서는 실제로 시간에 큰 영향을 미칩니다.

도움이 되었습니까?

해결책

글쎄, 당신이 배제했다면 Nullable<T>, 당신은 도메인 값이 남아 있습니다 - 즉 널로 취급하는 마법의 숫자. 이것은 그렇지 않습니다 이상적인, 예를 들어, 많은 주요 프레임 워크 코드가 취급하는 것도 드문 일이 아닙니다. DateTime.MinValue NULL과 동일합니다. 이것은 적어도 피해를 일반적인 값에서 멀리 떨어 뜨립니다 ...

NAN이없는 곳에 만 강조 표시하기 위해 편집하십시오

그래서 그렇지 않은 곳 NaN, 아마도 사용하십시오 .MinValue - 그러나 우연히 당신이 실수로 어떤 악이 일어난 일을 기억하십시오 사용 동일한 값을 같은 숫자를 의미합니다 ...

분명히 서명되지 않은 데이터의 경우 필요합니다 .MaxValue (피하기 !!!).

개인적으로, 나는 사용하려고 노력할 것입니다 Nullable<T> 내 의도를 더 안전하게 표현할 때 ... 최적화 할 수있는 방법이있을 수 있습니다. Nullable<T> 아마도 코드. 또한 - 당신이 필요한 모든 장소에서 마법 번호를 확인했을 때까지 Nullable<T>?

다른 팁

나는이 특정 엣지 케이스에서 Gravell에 다소 동의하지 않습니다. null-ed 변수는 '정의되지 않은'것으로 간주되며 값이 없습니다. 따라서 괜찮은 신호에 사용되는 것은 무엇이든 : 마법의 숫자조차도 마법의 숫자를 사용하면 갑자기 '유효한'가치가 될 때 마법의 숫자가 항상 당신을 괴롭힐 것임을 고려해야합니다. Double.nan을 사용하면 두려워 할 필요가 없습니다. 그것은 결코 유효한 두 배가되지 않을 것입니다. 그러나 Doubles 시퀀스의 의미에서 NAN은 '정의되지 않음'의 마커로만 사용할 수 있다고 생각해야합니다. 분명히 시퀀스에서 오류 코드로 사용할 수는 없습니다.

따라서 '정의되지 않은'을 표시하는 데 사용되는 것은 무엇이든 : 특정 값이 '정의되지 않은'의 값으로 간주되고 향후 변하지 않을 것이라는 값 세트의 맥락에서 명확해야합니다.

Nullable이 당신에게 너무 많은 어려움을 겪고 있다면, 당신이 결과를 고려하는 한, nan 또는 다른 것을 사용하십시오.

나는 NAN을 null 값. 나는 그것에 대해 완전히 편안하지 않습니다. 당신과 비슷한 이유로 무엇을 잘못 될 수 있는지 모릅니다. 우리는 지금까지 실제 문제에 직면하지 않았지만 다음을 알고 있어야합니다.

Nan 산술 - 대부분의 경우 "Nan Promotion"은 좋은 일이지만 항상 기대하는 것은 아닙니다.

비교 -NAN이 동일하게 비교하기를 원한다면 값 비교가 다소 비싸집니다. 이제 평등을 테스트하는 것은 어쨌든 간단하지는 않지만, 순서 (a <b)는 실제로 못 생겼을 수 있습니다. 왜냐하면 Nan의 경우 때로는 더 작고 때로는 일반 값보다 더 크기가 필요하기 때문입니다.

코드 감염 -NAN을 특정 처리 해야하는 산술 코드가 많이 있습니다. 따라서 성능의 이유로 "Nan 's를 수락하는 기능"과 "기능"으로 끝납니다.

다른 비정부 NAN은 유일한 비가 나이트 값입니다. 명심해야합니다 ...

부동 소수점 예외 장애가있을 때는 문제가되지 않습니다. 누군가가 그들을 가능하게 할 때까지. 실화 : ActiveX 컨트롤에서 NAN의 정적 강화. 파스칼/델파이 (?) 코어를 사용하는 innosetup을 사용하도록 설치를 변경할 때까지 무서워하지 않습니다. 알아내는 데 시간이 걸렸습니다.

따라서, 나는 자주 Nans를 고려하지 않아도되지만 진지한 것은 없습니다.


성능 / ressource 제약 조건이없는 한 무효 유형을 가능한 한 자주 사용합니다. 한 가지 경우는 가끔 NAN을 가진 큰 벡터 / 행렬 일 수 있거나 큰 개별 값의 큰 세트 일 수 있습니다. 기본 NAN 동작이 정확한 경우.


또는 벡터 및 행렬에 인덱스 벡터, 표준 "스파스 매트릭스"구현 또는 별도의 bool/비트 벡터를 사용할 수 있습니다.

부분 답변 :

플로트와 이중은 NAN (숫자가 아님)을 제공합니다. Nan은 Spec, Nan! = Nan 이후 약간 까다 롭습니다. 숫자가 NAN인지 알고 싶다면 Double.isnan ()을 사용해야합니다.

또한보십시오 바이너리 플로팅 포인트 및 .NET.

Nullable의 멤버 또는 속성 (권투) 중 하나를 호출 할 때 상당한 성능 감소가 발생할 수 있습니다.

Double + A Boolean과 함께 구조물을 사용하여 값이 지정되었는지 여부를 알려줍니다.

관련된 성능 저하를 피할 수 있습니다. Nullable<T> 자신의 구조를 정의함으로써

struct MaybeValid<T>
{
    public bool isValue;
    public T Value;
}

원하는 경우 생성자 또는 변환 연산자를 정의 할 수 있습니다. T 에게 MaybeValid<T>, 그러나 그러한 것들을 과도하게 사용하면 차선의 성능이 향상 될 수 있습니다. 불필요한 데이터 복사를 피하면 노출 된 필드 스트러크가 효율적일 수 있습니다. 어떤 사람들은 노출 된 분야의 개념에 눈살을 찌푸릴 수 있지만, 그 속성이 훨씬 더 효율적일 수 있습니다. a T 변수 유형이 필요합니다 T a MaybeValid<Foo> 단순히 반환 할 물건의 크기는 단순히 증가합니다. 대조적으로, a Nullable<Foo> 기능이 먼저 계산해야합니다 Foo 그런 다음 사본을 생성자에게 전달하십시오. Nullable<Foo>. 또한, 반환 a Nullable<Foo> 반환 된 값을 사용하려는 모든 코드는 유형의 스토리지 위치 (변수 또는 임시)에 하나 이상의 추가 사본을 작성해야합니다. Foo 그것에 유용한 일을하기 전에. 대조적으로 코드는 다음을 사용할 수 있습니다 Value 유형 변수 필드 Foo 다른 변수만큼 효율적으로.

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