[.NET][C#]大量New CultureInfo對效能的影響

同事在處理大量資料的轉檔,專案用C#讀取大量文字檔案,讀取後要做基本欄位檢核,因為程式處理速度較慢(10萬筆20分鐘),於是幫忙同事一起抓原因。花了幾個小時後,發現重複New CultureInfo 對效能帶來巨大的影響,快來筆記。

 

日期欄位的檢核:

通常我們會用Datetime.TryParse或DateTime.TryParseExact這兩種方法檢核並輸出日期值。

*兩者差別在輸入的日期字串是否為標準的格式(ISO8601),當字串可能是非標準的格式時,程式可以會使用Datetime.TryParseExact指定格式。

DateTime.TryParseExact(
"20150709", 
"yyyyMMdd", 
new CultureInfo("zh-TW", true), 
DateTimeStyles.None, 
out dteDTE)

*yyyyMMdd是ISO8601標準的格式,其實用TryParse也可以

 

參數說明:

其中第3個參數要輸入System.Globalization下的文化特性類別CultureInfo

這邊的寫法如果執行1次影響並不大,但因為這個段落要重複執行100萬次以上,時間就很漫長,來執行10萬次比較:

 

1.執行10萬次new CultureInfo (Datetime.TryParseExact)

[TestMethod]
public void TestMethod1()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < 100000; i++)
    {
        DateTime dteDTE = new DateTime();
        if (DateTime.TryParseExact("20150709", "yyyyMMdd", new CultureInfo("zh-TW", true), DateTimeStyles.None, out dteDTE))
        {
            continue;
        }
    }
    sw.Stop();
    Console.WriteLine(String.Format("總計時間:{0}毫秒", (sw.ElapsedMilliseconds).ToString()));
}

2.只執行1次new CultureInfo (Datetime.TryParseExact)

[TestMethod]
public void TestMethod2()
{
    CultureInfo culTW = new CultureInfo("zh-TW", true);
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < 100000; i++)
    {
        DateTime dteDTE = new DateTime();
        if (DateTime.TryParseExact("20150709", "yyyyMMdd", culTW, DateTimeStyles.None, out dteDTE))
        {
            continue;
        }
    }
    sw.Stop();
    Console.WriteLine(String.Format("總計時間:{0}毫秒", (sw.ElapsedMilliseconds).ToString()));
}

 

3.單純用Datatime.TryPasre

[TestMethod]
public void TestMethod3()
{

    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < 100000; i++)
    {
        DateTime dteDTE = new DateTime();
        if (DateTime.TryParse("20150709",out dteDTE))
        {
            continue;
        }
    }
    sw.Stop();
    Console.WriteLine(String.Format("總計時間:{0}毫秒", (sw.ElapsedMilliseconds).ToString()));
}

 

#Set ms
TryParseExact (new 10萬次 CultureInfo ) 32995
TryParseExact  (new 1次 CultureInfo ) 29
TryParse 20

 

 

小結:

  • 32995ms vs 29ms,揉眼睛,真的沒看錯!是1,000倍,這個比半澤直樹最終回百倍返しだ!(百倍奉還)還強!
  • 預計要轉200萬筆資料,33s * 20單位交易量 * 20個日期欄位 / 8t = 1650秒 ≃ 30分鐘節省
  • 選Datetime.TryParse或Datetime.TryParseExact都很快,只要不要選Datetime.Parse! 在轉換失敗時,效能會差很多。
  • 20150709是女兒生日。

 

 

 

參考:

CultureInfo 類別

C# - new CultureInfo instantiation performance

DateTime方法