.NET Alternative way to handle exception with low cost
ช่างนี้ได้รับงาน design new web server ทำให้ต้องศึกษาภาษาต่างๆมากมาย เช่น nodejs ,js,react,go,.netcore etc แล้วไปอ่านเจอความน่าสนใจของภาษา go ตามด้าน
f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
// do something with the open *File f
ทำให้นึกถึงภาษาหลักที่ใช้ในการทำงานอย่าง .NET โดยปกติเราจะเขียน Logic เพื่อ Validate เอาไว้ในลัษณะ throw exception ดังนี้
public double Cal(int p1, int p2)
{
if (p2 == 0)
{
throw new DivideByZeroException();
}
return (p1/p2);
}
แล้วใน Code ที่เรียกเราก็จะทำ Try Catch ครอบไว้อีกที
try{var result = calculator.Cal(1, 0);}
catch (Exception){// Exception here}
ตาม Exceptions and Performance ของ Microsoft ก็จะมีทางออก และวิธีการที่ควรทำ ทำให้ผมกลับมานั้งคิดว่ามันจำกิน Performance เยอะขนาดไหนสำหรับการ throw exception และ ใช้ try catch แบบปกติที่เราทำกัน
เริ่มต้นผมจะใช้ BenchmarkDotNet เพื่อทำการเปรียบเทียบว่าต่างกันแค่ไหน ตาม code ด้านล่าง
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;namespace Benchmark
{
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<TestFactory>();
Console.ReadLine();
}
}
public class Calculator
{ public (double, Exception) CalT(int p1, int p2)
{
if (p2 == 0)
{
return (0, new DivideByZeroException("p2 must grester than 0"));
}
return (p1 / p2, null);
}public double Cal(int p1, int p2)
{
if (p2 == 0)
{
throw new DivideByZeroException();
}
return (p1 / p2);
}
}
public class TestFactory
{
private Calculator calculator;
public TestFactory()
{
calculator = new Calculator();
}
[Benchmark]
public void test1()
{
try
{
var ret = calculator.Cal(1, 0);
}
catch (Exception)
{
// Exception here
}
}
[Benchmark]
public void test2()
{ var ret = calculator.CalT(1, 0); }
}
}
ผลลัพธ์ทำให้ตกใจว่า การเขียน Throw exception นั้นแพงมากเมื่อเทียบกับการจัดการ error แบบของที่ go ใช้ดังภาพด้านล่าง
ดูค่า mean แล้วตกใจ นี้ต้องกับไป refactor code กันดีหรือป่าวนะ LOL