เรื่องของ ambiguous match exception และการจัดการในมุม Performance

เจอคนในทีมแก้ Code มาแล้ว Error Ambiguous Match Exception

Ambiguous match exception คือ อะไร

ตอนเราเรียกใช้ Reflection ของ dotnet แล้วปรากฏว่า ผลลัพธ์ที่ได้ มันมี 2 ตัว โดย 2 ตัวยังไง เช่น

public class BaseClass
{
    public int MyProperty { get; set; }
    public int a { get; set; }
}

public class DerivedClass : BaseClass
{
    public new string MyProperty { get; set; }
    public int b { get; set; }
}

แล้วที่นี้มันจะมีแนวทางที่แก้ที่ถกกันนะ เพราะคนทำเค้าไม่อยู่ซะแล้ว

  • Get First เลย
  • Try Catch แล้ว เข้า AmbiguousMatchException ให้ลองอีกรอบ ดึงอีกรอบ โดยส่ง
    - BindingFlags.Instance
    - BindingFlags.Public
    - BindingFlags.DeclaredOnly

มีประเด็นเรื่อง Perf ผมเลยลองเขียน Code Test จับเวลา

using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

public class BaseClass
{
    public int MyProperty { get; set; }
    public int a { get; set; }
}

public class DerivedClass : BaseClass
{
    public new string MyProperty { get; set; }
    public int b { get; set; }
}

class Program
{
    static void Main()
    {
        Type type = typeof(DerivedClass);
        string path = "MyProperty";
        int iterations = 100000;

        // Benchmark first code snippet
        Stopwatch stopwatch1 = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            PropertyInfo[] infos = type.GetProperties();
            PropertyInfo info = infos.FirstOrDefault(p => p.Name.Equals(path, StringComparison.OrdinalIgnoreCase));
        }
        stopwatch1.Stop();
        Console.WriteLine($"First code snippet time: {stopwatch1.ElapsedMilliseconds} ms");

        // Benchmark second code snippet
        Stopwatch stopwatch2 = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            PropertyInfo info = null;
            try
            {
                info = type.GetProperty(path);
            }
            catch (AmbiguousMatchException)
            {
                info = type.GetProperty(path, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            }
        }
        stopwatch2.Stop();
        Console.WriteLine($"Second code snippet time: {stopwatch2.ElapsedMilliseconds} ms");
    }
}

ถ้าจะลอง Run สามารถเข้า https://dotnetfiddle.net/omhnmQ ได้ครับ

ส่วนผลลัพธ์ตามนี้

First code snippet time: 52 ms
Second code snippet time: 1558 ms

จะเห็นว่า Code ชุดแรกที่ไม่มีพวก Exception ดักไว้ มันจะใช้เวลาน้อยกว่าที่ดัก Exception นะ ซึ่งแบบหลักถ้ามันสะสมเยอะๆ มันจะกลายเป็นคอขวดอันใหญ่นะระบบได้น้า

ถ้าจะเลี่ยงเรื่องพวกนี้ต้องมาตกลง Coding Standard กันก่อน จะได้หลบปัญหาได้ และช่วยให้ App โดยรวมมี Perf ที่ดีขึ้นด้วย


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.