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.