Quickly create a cache key

I am using a custom cache implementation in Web Api 2. This cache stores hundreds of thousands of items and can be read 10,000 times or more in a single API request.

In profiling, I found that actually building the key cache of each item has a significant impact on overall performance.

Result from .NET profiling:

Sampling profiler

Cache key details:

I am creating an item key by hashing a string. For example:



This becomes hashed into something like this, which is then used in the caching framework as a key (this is no longer used - see EDIT 3):



Obviously I need to enforce the uniqueness of each key, but I cannot find a way to improve performance here without introducing possible duplication.

Key constructor:

public class CacheKeyBuilder
    private MethodInterceptionArgs methodArguments;

    public CacheKeyBuilder(MethodInterceptionArgs input)
        methodArguments = input;

    // No longer used - refer to EDIT 3
    public UInt64 GetHashedKey()
        return Hash(GetFriendlyKey());

    public string GetFriendlyKey()
        if (methodArguments.Arguments.OfType<IList>().Any())
            throw new ArgumentOutOfRangeException("Cannot create a keys from IList types");

        var type = methodArguments.Binding.GetType();

        var key = String.Format("{0}.{1}.{2}{3}{4}",
            type.UnderlyingSystemType.GenericTypeArguments.Select(x => x.Name).ToList().JoinItems("<", ">", ","),
            methodArguments.Arguments.Where(x => x != null).Select(x => x.ToString()).ToList().JoinItems("(", ")", ",")

        return key;

    // No longer used - refer to EDIT 3
    private UInt64 Hash(string key)
        UInt64 hashedValue = 3074457345618258791ul;

        for (int i = 0; i < key.Length; i++)
            hashedValue += key[i];
            hashedValue *= 3074457345618258799ul;

        return hashedValue;



  • To be unique, a keyword requires a namespace, a fully qualified type name, common elements, and all property values.
  • String.Format()

    essentially implements StringBuilder

    , so this should be the most efficient way to construct strings.
  • I got a hash from this post (Knuth hash?) Which is faster than my own previous implementations.

Are there any obvious performance improvements that can be made?


Another consideration, based on the comments by David and Patrick, is that I cannot hardcode the type string. Performance improvements should be backward compatible. I have to work with reflection.


Sorry, hash methods are meant to return UInt64

. Fixed code.


Storing the hashed key and friendly key did not affect performance. So I only go to GetFriendly()

. Thanks usr.


source to share

1 answer

It looks like you are using PostSharp. Their own example for caching generates the method name as a string at compile time.

It seems you can get the full type name at the same time. This would avoid expensive compile-time reflection.

public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    _methodName = method.Name;
    _typeName = method.Binding.GetType().Namespace...  ..Name; // etc


I would also try StringBuilder.Append()

vs string.Format()

and see if there is a shape difference.



All Articles