Double.TryParse 또는 Convert.ToDouble-어느 것이 더 빠르고 안전합니까?


80

내 응용 프로그램은 VSTO를 사용하여 Excel 파일을 읽고 읽은 데이터를 StringDictionary. 숫자가 몇 개인 데이터 만 추가합니다 (1000 1000,2 1000,34-쉼표는 러시아 표준에서 구분 기호입니다).

현재 문자열이 적절한 숫자인지 확인하는 것이 더 낫습니까?

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

또는

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

다음 구문 분석 알고리즘 문제 때문에 StringDictionary대신 사용해야 Dictionary<string, double>합니다.

내 질문 : 어느 쪽이 더 빠릅니까? 어느 것이 더 안전합니까?

Convert.ToDouble(object)또는 전화하는 것이 더 낫 Convert.ToDouble(string)습니까?


참고로, double.TryParse는 try {result = double.Parse (s); true를 반환하십시오. } catch {return false; }. Convert는 본질적으로 많은 오버로드가있는 두 가지 모두에 대한 래퍼입니다. 그것은 당신이 그것을하는 방법에 차이가 없습니다. 그러나 Jon이 지적했듯이 잘못된 입력을 처리하는 방법에 대해 생각하십시오.
John Leidegren

12
Double.TryParse는 try..catch에 래핑 된 double.Parse와 동일하지 않습니다. 의미는 동일하지만 코드 경로는 다릅니다. TryParse는 먼저 내부 Number.TryStringToNumber를 사용하여 문자열이 숫자인지 확인하는 반면 Parse는 이미 숫자 / 더블이라고 가정합니다.
Jeff Moser

답변:


131

릴리스 모드에서 빠른 비 과학적 테스트를 수행했습니다. 두 가지 입력을 사용했습니다 : "2.34523"과 "badinput"을 두 메서드에 모두 1,000,000 번 반복했습니다.

유효한 입력 :

Double.TryParse = 646ms
Convert.ToDouble = 662 ms

예상대로 크게 다르지 않습니다. 모든 의도와 목적을 위해 유효한 입력을 위해 이들은 동일합니다.

잘못된 입력:

Double.TryParse = 612ms
Convert.ToDouble = ..

음 .. 오랜만에 달렸어요. 1,000 번의 반복을 사용하여 전체를 다시 실행했고 Convert.ToDouble잘못된 입력으로 8.3 초가 걸렸습니다. 평균을 내면 2 시간 이상 걸립니다. 유효하지 않은 입력의 경우 테스트가 얼마나 기본적인지 신경 쓰지 않습니다.Convert.ToDouble '예외 발생으로 인해 성능이 저하됩니다.

그래서, TryParse그것을 뒷받침 할 몇 가지 숫자를 가진 또 다른 투표가 있습니다.


4
위에서 언급 한 것 외에도 Convert.ToDouble ()이 과학적 표기법으로 숫자와 함께 예외를 throw한다는 것을 방금 발견했습니다. 이것을 고려하십시오 : double toDouble = Convert.ToDouble ((-1/30000) .ToString ()); // 실패 double dblParse = Double.Parse ((-1/30000) .ToString ()); // 잘 작동합니다
Buddy Lee

46

우선, 나는 애초에 사용하는 double.Parse것이 아니라 사용 Convert.ToDouble합니다.

Parse또는 사용 여부에 관해서 TryParse: 잘못된 입력 데이터가 있으면 계속 진행할 수 있습니까? 아니면 정말 예외적 인 조건입니까? 예외적이라면 사용 Parse하고 입력이 나쁘면 날려 버리십시오. 예상하고 깔끔하게 처리 할 수있는 경우 TryParse.


6
Jon, 왜 double.Parse를 Convert.ToDouble보다 선호하는지 자세히 설명해 주시겠습니까?
David North

10
@dnorthut : 기본적으로 null이 0으로 변환되는 것을 거의 원하지 않습니다 (Convert.ToDouble이 수행합니다). 또한 일반적으로 더 유연합니다. 나는 단지 특정한 방법
Jon Skeet

8

.NET Framework 디자인 지침에서는 Try 메서드 사용을 권장합니다. 예외를 피하는 것은 일반적으로 좋은 생각입니다.

Convert.ToDouble(object) 할 것이다 ((IConvertible) object).ToDouble(null);

전화 할 것 Convert.ToDouble(string, null)

따라서 문자열 버전을 호출하는 것이 더 빠릅니다.

그러나 문자열 버전은 다음을 수행합니다.

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

따라서 double.Parse직접 수행하는 것이 더 빠릅니다 .


7

예외를 처리하지 않으려면 TryParse를 사용하십시오. TryParse는 전체 예외 스택 추적을 처리 할 필요가 없기 때문에 더 빠릅니다.


7

나는 일반적으로 Convert클래스 를 피하려고합니다 (의미 : 사용하지 않습니다). 왜냐하면 매우 혼란 스럽기 때문입니다. 코드는 여기서 정확히 무슨 일이 일어나는지에 대한 힌트를 너무 적게 제공합니다.Convert 동일한 코드에서 의미 상 매우 다른 변환이 많이 발생할 수 . 이것은 프로그래머가 정확히 무슨 일이 일어나고 있는지 제어하기 어렵게 만듭니다.

그러므로 나의 충고는 절대이 수업을 사용하지 말라는 것입니다. 실제로 필요하지도 않습니다 (숫자의 이진 형식화는 예외 ToString입니다. 숫자 클래스 의 일반적인 방법은이를 수행하는 적절한 방법을 제공하지 않기 때문입니다 ).


7

입력을 100 % 확신하지 않는 한 Double.TryParse를 사용해야합니다.

Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.

예외보다 훨씬 느리지 않기 때문에 예외를 던질 때 구문 분석 속도가 부차적입니다.


4

여기에 Convert 클래스에 대한 많은 증오가 있습니다. 약간의 균형을 맞추기 위해 Convert에 대한 한 가지 이점이 있습니다.

Convert.ToDouble(o);

o가 이미 Double (또는 int 또는 쉽게 캐스팅 할 수있는 모든 것)이면 값을 쉽게 반환 할 수 있습니다.

Double.Parse 또는 Double.TryParse를 사용하는 것은 이미 문자열에있는 경우 유용하지만

Double.Parse(o.ToString());

가야 문자열이 제 더 비싼이 될 수 귀하의 의견에 따라 구문 분석 할 수 있습니다.


1
+1 : 당신의 관점을 봅니다. System.Object 내부의 숫자로 박스형 숫자 / 문자열을 구문 분석하는 것은 매우 쉽습니다. 하지만 기본적으로 다른 답변에 동의합니다. Convert.ToSomething()특히 반복 컨텍스트에서 Parse / TryParse보다 훨씬 비쌉니다.
T-moty

나에게 Convert.ToDouble (o)는 상자 안에있는 것이 이미 숫자이면 몇 가지 쉬운 아웃을 가지고 있지만 Convert의 진정한 킬러는 .TryToDouble (o, out d)가 없다는 것입니다. 예외가 얼마나 비싸고 (그리고 입력에 대해 얼마나 확신하는지 여부)를 감안할 때 이는 Convert의 큰 추가 비용입니다.
user1664043

2

Double.TryParse IMO.

처리하기가 더 쉽습니다. 오류가 발생한 위치를 정확히 알 수 있습니다.

그런 다음 false를 반환하는 경우 (즉, 변환 할 수없는 경우) 적합하다고 판단되는 방식으로 처리 할 수 ​​있습니다.


2

TryParse()예외에 대해 걱정할 필요없이 변환 성공 또는 실패를 되돌릴 수 있기 때문에 항상 메서드를 사용하는 것을 선호 했습니다.


2

이것은 흥미로운 오래된 질문입니다. 아무도 원래 질문에서 몇 가지를 알아 차리지 않았기 때문에 답변을 추가하고 있습니다.

어느 것이 더 빠릅니까? Convert.ToDouble 또는 Double.TryParse? 어느 것이 더 안전합니까? Convert.ToDouble 또는 Double.TryParse?

이 두 가지 질문에 대해 자세히 답변하겠습니다 (나중에 답변을 업데이트하겠습니다).하지만 먼저 :

안전을 위해 모든 프로그래머가이 질문에서 놓친 부분은 다음과 같습니다.

숫자가 몇 개인 데이터 만 추가합니다 (1000 1000,2 1000,34- 쉼표는 러시아 표준에서 구분 기호입니다 ).

다음 코드 예제가 이어집니다.

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

여기서 흥미로운 점은 스프레드 시트가 러시아어 숫자 형식이지만 Excel에서 셀 필드를 올바르게 입력하지 않은 경우 Excel에서 들어오는 값의 올바른 해석은 무엇입니까?

속도와 관련하여 두 가지 예에 대한 또 다른 흥미로운 점이 있습니다.

catch (InvalidCastException)
{
    // is not a number
}

이것은 다음과 같은 MSIL을 생성 할 것입니다.

catch [mscorlib]System.InvalidCastException 
{
  IL_0023:  stloc.0
  IL_0024:  nop
  IL_0025:  ldloc.0
  IL_0026:  nop
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  leave.s    IL_002f
}  // end handler
IL_002f: nop
IL_0030: return

이런 의미에서 우리는 아마도 각 프로그램이 수행하는 MSIL 명령어의 총 수를 비교할 수있을 것입니다.

나는 코드가 정확하고, 명확하고, 빠르다고 믿는다 ... 그 순서대로!


1

개인적으로, 나는 TryParse당신이 실제로 사용하고 싶은 방법이 당신의 사용 사례에 따라 더 읽기 쉽다 는 것을 발견했습니다 . 오류를 로컬에서 처리 할 수 ​​있다면 당신은 오류와 bool을 기대하게됩니다.TryParse 이 좋은 것입니다. 예외는 날아갑니다.

TryParse예외 처리의 오버 헤드를 피할 수 있기 때문에 더 빠를 것으로 기대합니다 . 그러나 Jon Skeet의 MiniBench 와 같은 벤치 마크 도구 를 사용하여 다양한 가능성을 비교하십시오.


이 답변에 대한 피드백 : 질문에서 무엇이 더 빠르고 안전한지 묻는 경우, 답변은 "개인적으로"로 시작해서는 안되며 "예상합니다 ..."와 같은 추측을 포함해야합니다. 이것은 좋은 대답이 아니라 개인적인 생각과 논평 일뿐입니다.
PandaWood
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.