2010-04-29 3 views
4

일부 사용자 지정 직렬화 작업을하고 일부 공간을 절약하기 위해 가능하면 현명한 값으로 int로 소수 자릿수를 직렬화하려고합니다. 나는 많은 양의 데이터를 다루고 있기 때문에 성능 문제가있다. 현재 사용하는 방법은 다음과 같습니다.십진수를 int32로 저장할 수 있는지 확인하십시오.

if ((value > Int32.MinValue) && (value < Int32.MaxValue) && ((valueAsInt = Decimal.ToInt32(value)) == value)) 
{ 
    return true; 
} 

개선 될 수 있습니까?

+0

성능에 대해서는 계속 이야기하지만 벤치 마크 나 특정 요구 사항은 표시되지 않습니다. 이 방법이 성능이 좋지 않다는 것을 어떻게 알 수 있습니까? 얼마나 개선 될 것으로 예상됩니까? 당신이 그것을 성취했는지 어떻게 알 수 있습니까? – Aaronaught

+0

@aaronaught이 방법이 성능이 좋지 않다고 말하는 것은 아니지만 이것이 더 효율적 일 수는 없음을 의미하지는 않습니다. 내가 가지고있는 데이터의 양에 대해, 일어나는 일을 직렬화하고 분석 할 때,이 코드 조각은 4 %의 CPU 시간을 소비했다. 더 적은 것은 개선이다. 즉, 나는 숫자 표현이나 일리노이 실행의 내적 작업에 대한 전문가가 아니기 때문에이 분야에 대한 지식이 부족하기 때문에 개선의 여지가있을 수 있습니다. – anchandra

+0

"성능"도 실행하는 데 걸리는 시간을 측정 할 수 있습니다. CPU가 4 % 밖에 안되면 멀티 스레드로 CPU를 더 많이 사용하고 더 빨리 끝낼 수 있습니다. 또는이 코드가 총 CPU 사용량의 4 %를 차지했거나 (아마 100 %에 가깝습니다) 오해 했습니까? –

답변

1

음수 값을 갖고 있습니까? MinValue 검사를 했으므로 예를 추측하고 있습니다. 그렇지 않으면 건너 뛸 수 있습니다. 심지어 double 값을 int로 변환 할 수있는 unsigned int를 사용할 수도 있습니다.

편집 : 또한 더 많은 양수가 있으면 처음 두 조건을 바꿀 수 있습니다. 그런 식으로 첫 번째 오류가 발생할 확률이 가장 높으므로 총 비교 횟수가 줄어 듭니다.

+0

모든 소수 자릿수의 값을 가질 수 있습니다. 정밀도는 큰 관심사입니다. – anchandra

+0

사실 그것은 매우 좋은 지적입니다. 나는이면을 조사 할 것이다. 감사합니다 – anchandra

+0

숫자/요구 사항의 성격에 따라 짧은, int 및 long, 심지어 double 및 float 사용을 고려할 수 있습니다 (그러나 정밀도 손실에주의하십시오).최적의 유형을 결정해야하므로 전환에 더 오래 걸리지 만 공간을 절약 할 수 있습니다. 병목 현상이 CPU가 아닌 공간 또는 전송 속도 (예 : 느린 인터넷 연결) 인 경우이 방법이 유용 할 수 있습니다. –

1

귀하의 무효화 기준은 다음과 같습니다 :

1) MaxValue보다 큽니까?

2) MinValue보다 작습니까?

3) 분수 성분을 포함합니까?

소리가 들리는 것 같습니다. 내 구현은 다음과 같습니다

if(Decimal.ToInt32(value) == value) 
{ 
    return true; 
} 

하지 .NET에 대한 전문가,하지만 난 그게 필요한 것 모두해야한다고 생각 :

public bool IsConvertibleToInt(decimal value) 
{ 
    if(value > int.MaxValue) 
     return false; 

    if(value < int.MinValue) 
     return false; 

    if(Math.Floor(value) < value && Math.Ceiling(value) > value) 
     return false; 

    return true; 
} 
+0

내 솔루션이 작동합니다, 나는 그것이 가속 될 수 있는지 궁금 해서요. 감사합니다 – anchandra

0

당신처럼 뭔가를 할 수 없을 것입니다. 또한 최소/최대 값도 유효하기 때문에 두 비교 연산자는 '같거나 같아야합니다.

편집 : 의견에서 지적한대로 예외가 발생합니다. 당신은 예외를 잡아서 false를 반환하려고 할 수 있지만, 그 시점에서 min/max 테스트를하는 것이 훨씬 더 빠를 것입니다.

+1

@Kitsune : 값이 너무 큰 경우 예외가 발생합니다. – RedFilter

+0

@Kitsune : 기능상의 문제가 아니라 성능 문제입니다. 현재의 솔루션이 제대로 작동하지만 성능을 향상시킬 수 있는지 알고 싶습니다. – anchandra

+0

@anchandra : 그렇습니다. 그 이유는이 기능을 사용하지 않는 것이 좋습니다. 느린 속도로 더 이상 읽을 수 없기 때문입니다. – Kitsune

1

어때? 나는 그것이 더 적은 작업을 (비교 적어도 적은 수의)해야한다고 생각 : if 문이 단순히 부울을 반환하는 경우

return (value == (Int32)value); 

또한 기억, 당신은 단지 비교를 반환 할 수 있습니다. 이것만으로도 컴파일러가 이미이를 최적화하지 않는 한 더 빠르게 만들 수 있습니다. 당신은 if 문을 사용하는 경우, 당신은 유사하게이 작업을 수행 할 수 있습니다

if (value == (Int32)value) 
    { 
     //Do stuff... 
    return true; 
    } 
    else 
    { 
     //Do stuff... 
     return false; 
    } 

편집 : 나는 실현이 실제로 작동하지 않습니다. 나는 Int32 캐스트가 단지 나머지 32 비트를 남겨두고 (예외를 던지지 않음) 소수점에서 처음 32 비트를 복사 할 것이라고 생각했지만, 슬프게도 그렇게 작동하지 않았습니다. 모든 음수 값).

+1

@smoore : 값이 너무 큰 경우 예외가 발생합니다. – RedFilter

+0

젠장, 네 말이 맞아! –

+0

@OrbMan : 안전하지 않으면 트릭을하고 강제로 캐스팅을 수행 하시겠습니까? –

0

"valueAsInt ="가 필요하지 않습니다. 나는 (Decimal.ToInt32 (value) == value))는 적은 결과로 적은 결과를 얻을 수 있다고 믿는다. 일종의 출력 매개 변수로 valueAsInt를 사용하고 있습니까?

+0

출력 매개 변수로 필요하지만 더 효율적인 방법으로 int 값을 결정할 수 있는지 의문이 생깁니다. – anchandra

1

당신이 가지고 있거나 정말로 신경 써야 할 소수 자리 수에 따라 다릅니다. 내가 소수점 이하 3 자리까지만 처리하면 int32에 저장할 수있는 최대 숫자는 int.MaxValue/1000입니다. 양수로만 작업하는 경우에는 uint를 사용하여 더 높은 숫자를 얻을 수 있습니다. 어쨌든 그것을하기위한 방법은 일관되게 소수를위한 공간을 확보하고 그것들을 인코딩하기 위해 * 1000을 사용하고 그것들을 십진수로 /에서 십진수로 디코딩하는 것입니다.

+0

불행히도 정밀도에 제한을 두지 못합니다. – anchandra

관련 문제