StackExchange redis client very slow compared to benchmark tests : <p>I'm implementing a Redis caching layer using the Stackexchange Redis client and the performance right now is bordering on unusable.</p>

<p>I have a local environment where the web application and the redis server are running on the same machine.  I ran the Redis benchmark test against my Redis server and the results were actually really good (I'm just including set and get operations in my write up):</p>

<pre><code>C:\Program Files\Redis&gt;redis-benchmark -n 100000
====== PING_INLINE ======
  100000 requests completed in 0.88 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

====== SET ======
  100000 requests completed in 0.89 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

99.70% &lt;= 1 milliseconds
99.90% &lt;= 2 milliseconds
100.00% &lt;= 3 milliseconds
111982.08 requests per second

====== GET ======
  100000 requests completed in 0.81 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

99.87% &lt;= 1 milliseconds
99.98% &lt;= 2 milliseconds
100.00% &lt;= 2 milliseconds
124069.48 requests per second
</code></pre>

<p>So according to the benchmarks I am looking at over 100,000 sets and 100,000 gets, per second.  I wrote a unit test to do 300,000 set/gets:</p>

<pre><code>private string redisCacheConn = "localhost:6379,allowAdmin=true,abortConnect=false,ssl=false";


[Fact]
public void PerfTestWriteShortString()
{
    CacheManager cm = new CacheManager(redisCacheConn);

    string svalue = "t";
    string skey = "testtesttest";
    for (int i = 0; i &lt; 300000; i++)
    {
        cm.SaveCache(skey + i, svalue);
        string valRead = cm.ObtainItemFromCacheString(skey + i);
     }

}
</code></pre>

<p>This uses the following class to perform the Redis operations via the Stackexchange client:</p>

<pre><code>using StackExchange.Redis;    

namespace Caching
{
    public class CacheManager:ICacheManager, ICacheManagerReports
    {
        private static string cs;
        private static ConfigurationOptions options;
        private int pageSize = 5000;
        public ICacheSerializer serializer { get; set; }

        public CacheManager(string connectionString)
        {
            serializer = new SerializeJSON();
            cs = connectionString;
            options = ConfigurationOptions.Parse(connectionString);
            options.SyncTimeout = 60000;
        }

        private static readonly Lazy&lt;ConnectionMultiplexer&gt; lazyConnection = new Lazy&lt;ConnectionMultiplexer&gt;(() =&gt; ConnectionMultiplexer.Connect(options));
        private static ConnectionMultiplexer Connection =&gt; lazyConnection.Value;
        private static IDatabase cache =&gt; Connection.GetDatabase();

        public string ObtainItemFromCacheString(string cacheId)
        {
            return cache.StringGet(cacheId);
        }

        public void SaveCache&lt;T&gt;(string cacheId, T cacheEntry, TimeSpan? expiry = null)
        {
            if (IsValueType&lt;T&gt;())
            {
                cache.StringSet(cacheId, cacheEntry.ToString(), expiry);
            }
            else
            {
                cache.StringSet(cacheId, serializer.SerializeObject(cacheEntry), expiry);
            }
        }

        public bool IsValueType&lt;T&gt;()
        {
            return typeof(T).IsValueType || typeof(T) == typeof(string);
        }

    }
}
</code></pre>

<p>My JSON serializer is just using Newtonsoft.JSON:</p>

<pre><code>using System.Collections.Generic;
using Newtonsoft.Json;

namespace Caching
{
    public class SerializeJSON:ICacheSerializer
    {
        public string SerializeObject&lt;T&gt;(T cacheEntry)
        {
            return JsonConvert.SerializeObject(cacheEntry, Formatting.None,
                new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                });
        }

        public T DeserializeObject&lt;T&gt;(string data)
        {
            return JsonConvert.DeserializeObject&lt;T&gt;(data, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });

        }


    }
}
</code></pre>

<p>My test times are around 21 seconds (for 300,000 sets and 300,000 gets).  This gives me around 28,500 operations per second (at least 3 times slower than I would expect using the benchmarks).  The application I am converting to use Redis is pretty chatty and certain heavy requests can approximate 200,000 total operations against Redis. Obviously I wasn't expecting anything like the same times I was getting when using the system runtime cache, but the delays after this change are significant.  Am I doing something wrong with my implementation and does anyone know why my benchmarked figures are so much faster than my Stackechange test figures?</p>

<p>Thanks,
Paul</p>
