C# 中Parse 和TryParse的效率问题
来源:互联网 发布:js身份证号码格式验证 编辑:程序博客网 时间:2024/05/18 23:56
我们知道在C#中数值类型中转换有Parse和TryParse两个方法,两个最大的区别是,如果字符串不满足转换要求,Parse方法将会引发一个异常;TryParse方法则不会引发异常,它会返回fasle,同时将传入的值置为0。
下面我用测试用例来验证两者的效率问题:
测试转换成功的效率问题:
同过上面的图片可以看到 在转换成功时,效率方面TryParse 略微占了上风。
测试转换失败效率的问题
通过这个测试可以发现TryParse的效率明显高于Parse,当然读者还可以测试其它类型的转换。
可是为什么TryParse的效率比Parse的效率高呢?建议读者看看源码就明白了。
微软提供的代码如下:
Parse 相关代码如下:
[Pure] public static int Parse(String s) { return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo); } [System.Security.SecuritySafeCritical] // auto-generated internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) { Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes]; NumberBuffer number = new NumberBuffer(numberBufferBytes); Int32 i = 0; StringToNumber(s, style, ref number, info, false); if ((style & NumberStyles.AllowHexSpecifier) != 0) { if (!HexNumberToInt32(ref number, ref i)) { throw new OverflowException(Environment.GetResourceString("Overflow_Int32")); } } else { if (!NumberToInt32(ref number, ref i)) { throw new OverflowException(Environment.GetResourceString("Overflow_Int32")); } } return i; } [System.Security.SecuritySafeCritical] // auto-generated private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal) { if (str == null) { throw new ArgumentNullException("String"); } Contract.EndContractBlock(); Contract.Assert(info != null, ""); fixed (char* stringPointer = str) { char * p = stringPointer; if (!ParseNumber(ref p, options, ref number, null, info , parseDecimal) || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } } } private static Boolean HexNumberToInt32(ref NumberBuffer number, ref Int32 value) { UInt32 passedValue = 0; Boolean returnValue = HexNumberToUInt32(ref number, ref passedValue); value = (Int32)passedValue; return returnValue; }[System.Security.SecuritySafeCritical] // auto-generated private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value) { Int32 i = number.scale; if (i > UInt32Precision || i < number.precision) { return false; } Char* p = number.digits; Contract.Assert(p != null, ""); UInt32 n = 0; while (--i >= 0) { if (n > ((UInt32)0xFFFFFFFF / 16)) { return false; } n *= 16; if (*p != '\0') { UInt32 newN = n; if (*p != '\0') { if (*p >= '0' && *p <= '9') { newN += (UInt32)(*p - '0'); } else { if (*p >= 'A' && *p <= 'F') { newN += (UInt32)((*p - 'A') + 10); } else { Contract.Assert(*p >= 'a' && *p <= 'f', ""); newN += (UInt32)((*p - 'a') + 10); } } p++; } // Detect an overflow here... if (newN < n) { return false; } n = newN; } } value = n; return true; }
TryParse的相关代码
[Pure] public static bool TryParse(String s, out Int32 result) { return Number.TryParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result); } [System.Security.SecuritySafeCritical] // auto-generated internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) { Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes]; NumberBuffer number = new NumberBuffer(numberBufferBytes); result = 0; if (!TryStringToNumber(s, style, ref number, info, false)) { return false; } if ((style & NumberStyles.AllowHexSpecifier) != 0) { if (!HexNumberToInt32(ref number, ref result)) { return false; } } else { if (!NumberToInt32(ref number, ref result)) { return false; } } return true; } internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, Boolean parseDecimal) { return TryStringToNumber(str, options, ref number, null, numfmt, parseDecimal); } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.CompilerServices.FriendAccessAllowed] internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) { if (str == null) { return false; } Contract.Assert(numfmt != null, ""); fixed (char* stringPointer = str) { char * p = stringPointer; if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal) || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) { return false; } } return true; }
完整的源代码如下:
https://referencesource.microsoft.com/#mscorlib/system/int32.cs,225942ed7b7a3252
在打开的网页中直接搜索Parse和TryParse ,便看到对应的源码了。
相关测试的代码如下:
using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Text;using System.Threading.Tasks;namespace EfficietionProject{ class Program { static string val = "123a"; static void Main(string[] args) { int counter = 1; Console.Write("输入测试的数量:"); string line = null; while ((line = Console.ReadLine()) != null) { if (!int.TryParse(line, out counter)) { counter = 1; } Stopwatch sw = Stopwatch.StartNew(); Parse(counter); sw.Stop(); Console.WriteLine("Parse:" + sw.ElapsedMilliseconds.ToString()); sw.Restart(); TryParse(counter); sw.Stop(); Console.WriteLine("TryParse:" + sw.ElapsedMilliseconds.ToString()); Console.Write("输入测试的数量:"); } } static void Parse(int counter) { int res = 0; for (int i = 0; i < counter; i++) { try { res = int.Parse(val); } catch { res = 0; } } } static void TryParse(int counter) { int res = 0; for (int i = 0; i < counter; i++) { int.TryParse(val, out res); } } }}
1 0
- C# 中Parse 和TryParse的效率问题
- C# TryParse 和 Parse
- c# Parse 和 TryParse
- 有关C#中in.Parse()和int.TryParse()的一点思考
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
- parse和Tryparse区别
- Parse和TryParse区别
- Parse和TryParse
- Parse 和 TryParse
- 在c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32()四种转换的区别
- c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32的区别
- c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32()四种转换的区别
- 在c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32()四种转换的区别
- c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32的区别
- c#中 (int)、int.Parse()、int.TryParse、Convert.ToInt32的区别
- php中(文件下载)
- redis基础知识汇总
- hive安装(本地mariaDB为元数据库)
- C语言共用体(Union)
- 搭建CentOS在线yum源镜像服务器
- C# 中Parse 和TryParse的效率问题
- 用CSS3实现带小三角形的div框(不用图片)
- 关键字static,静态
- MySQL一些函数的使用
- memcache
- C语言枚举类型(Enum)
- android thread 和service的区别
- CI框架(无限级分类+递归)
- Java程序打包成jar包