totpero/DeviceDetector.NET

LRU cache for improved performance when parsing duplicate User Agents

stbentia opened this issue · 1 comments

I appreciate all of the work by others on speeding up DeviceDetector.NET's parsing and on caching the regex. For me, I noticed my code (used on a website) would parse the same User Agent repeatedly, so I wrapped DeviceDetector in an LRUCache based on this project: https://gist.github.com/eladmarg/8d4a7f7a43a36c35d488e99475a101d9

This won't help for parsing mostly unique User Agents, but this made a huge difference in my case, so I thought I'd share. The maximum cache size of 10,000 and duration of 10 minutes may need to be changed depending on the use case, but they yield a 95%+ cache hit rate for me.

[To use: var dd = LRUCachedDeviceDetector.GetDeviceDetector(userAgent);]

public class LRUCachedDeviceDetector
{
    private static readonly DictionaryCache deviceCache;
    private static readonly GenericLRUCache<string, DeviceDetector> lruDeviceDetector;

    static LRUCachedDeviceDetector()
    {
        deviceCache = new DictionaryCache();

        lruDeviceDetector = new GenericLRUCache<string, DeviceDetector>(maxSize: 10_000, cleanPercentage: 30, maxDuration: TimeSpan.FromMinutes(10));
    }

    public static DeviceDetector GetDeviceDetector(string userAgent)
    {
        if (!lruDeviceDetector.TryGetValue(userAgent, out var dd))
        {
            dd = new DeviceDetector(userAgent);
            dd.SetCache(deviceCache);
            dd.Parse();
            lruDeviceDetector.AddToCache(userAgent, dd);
        }
        return dd;
    }
}

Thanks for sharing this man, I wish it was directly part of the library.