Permalink
Browse files

Switching from Activator.CreateInstance to a caching version

  • Loading branch information...
1 parent 8a8a632 commit 69264e29db0f85a3597fa62ce11d77b78698b25e @drusellers drusellers committed Sep 14, 2012
@@ -56,7 +56,7 @@ private string ExecuteView()
private string ExecuteView(StubViewData viewData)
{
- var view = (StubSparkView)Activator.CreateInstance(_compiler.CompiledType);
+ var view = FastActivator<StubSparkView>.New(_compiler.CompiledType);
_languageFactory.InstanceCreated(_compiler, view);
view.ViewData = viewData;
var contents = new StringWriter();
@@ -71,7 +71,7 @@ public void CreatedViewHasScriptProperty()
{
var chunks = Chunks(new SendLiteralChunk { Text = "Hello" });
_compiler.CompileView(chunks, chunks);
- var view = (IScriptingSparkView)Activator.CreateInstance(_compiler.CompiledType);
+ var view = FastActivator<IScriptingSparkView>.New(_compiler.CompiledType);
var source = _compiler.SourceCode;
var script = view.ScriptSource;
Assert.IsNotNull(source);
@@ -56,7 +56,7 @@ private string ExecuteView()
private string ExecuteView(StubViewData viewData)
{
- var view = (StubSparkView)Activator.CreateInstance(_compiler.CompiledType);
+ var view = FastActivator<StubSparkView>.New(_compiler.CompiledType);
_languageFactory.InstanceCreated(_compiler, view);
view.ViewData = viewData;
var contents = new StringWriter();
@@ -71,7 +71,7 @@ public void CreatedViewHasScriptProperty()
{
var chunks = Chunks(new SendLiteralChunk { Text = "Hello" });
_compiler.CompileView(chunks, chunks);
- var view = (IScriptingSparkView)Activator.CreateInstance(_compiler.CompiledType);
+ var view = FastActivator<IScriptingSparkView>.New(_compiler.CompiledType);
var source = _compiler.SourceCode;
var script = view.ScriptSource;
Assert.IsNotNull(source);
@@ -14,6 +14,7 @@
//
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -78,6 +79,17 @@ public void CreateViewInstance()
}
[Test]
+ public void FastCreateViewInstance()
+ {
+ var type = typeof(TestView);
+ var factory = new FastViewActivator();
+ var activator = factory.Register(type);
+ var view = activator.Activate(type);
+ Assert.IsNotNull(view);
+ Assert.IsAssignableFrom(typeof(TestView), view);
+ }
+
+ [Test]
public void CustomViewActivator()
{
var engine = new SparkViewEngine(
@@ -93,5 +105,38 @@ public void CustomViewActivator()
Assert.IsNotNull(view);
Assert.IsAssignableFrom(typeof(TestView), view);
}
+
+ [Test, Explicit]
+ public void PerfTest()
+ {
+ var type = typeof(TestView);
+ var defFactory = new DefaultViewActivator();
+ var fastFactory = new FastViewActivator();
+
+ var activator = defFactory.Register(type);
+ var fastActivator = fastFactory.Register(type);
+ var iterations = 1000000;
+
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
+
+ for (int i = 0; i < iterations; i++)
+ {
+ var view = activator.Activate(type);
+ }
+ sw.Stop();
+
+ Console.WriteLine("Default took: {0}ms", sw.Elapsed.TotalMilliseconds);
+ sw.Reset();
+
+ sw.Start();
+
+ for (int i = 0; i < iterations; i++)
+ {
+ var view = fastActivator.Activate(type);
+ }
+ sw.Stop();
+ Console.WriteLine("Fast took: {0}ms", sw.Elapsed.TotalMilliseconds);
+ }
}
}
@@ -13,11 +13,8 @@
// limitations under the License.
//
using System;
-using System.Linq;
using System.Collections.Generic;
-using System.Text;
-using Spark.Compiler.ChunkVisitors;
-using Spark;
+using System.Linq.Expressions;
namespace Spark.Compiler
{
@@ -53,10 +50,30 @@ public string TargetNamespace
public abstract void CompileView(IEnumerable<IList<Chunk>> viewTemplates, IEnumerable<IList<Chunk>> allResources);
public abstract void GenerateSourceCode(IEnumerable<IList<Chunk>> viewTemplates, IEnumerable<IList<Chunk>> allResources);
+
+
+ private static Dictionary<Type, Func<ISparkView>> _ctors = new Dictionary<Type, Func<ISparkView>>();
public ISparkView CreateInstance()
{
- return (ISparkView)Activator.CreateInstance(CompiledType);
+ return FastActivator<ISparkView>.New(CompiledType);
}
}
+
+ public static class FastActivator<TTargetClass> where TTargetClass : class
+ {
+ private static Dictionary<Type, Func<TTargetClass>> _ctors = new Dictionary<Type, Func<TTargetClass>>();
+
+ public static TTargetClass New(Type type)
+ {
+ if (!_ctors.ContainsKey(type))
+ {
+ var exp = Expression.New(type);
+ var d = Expression.Lambda<Func<TTargetClass>>(exp).Compile();
+ _ctors.Add(type, d);
+ }
+
+ return _ctors[type]();
+ }
+ }
}
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Spark
+{
+ public class FastViewActivator : IViewActivatorFactory, IViewActivator
+ {
+ private static Dictionary<Type, Func<ISparkView>> _ctors = new Dictionary<Type, Func<ISparkView>>();
+
+ public IViewActivator Register(Type type)
+ {
+ //you could put a guard clause in here too to ensure the type can be cast to ISparkView
+ if (_ctors.ContainsKey(type)) return this;
+
+ var exp = Expression.New(type);
+ var d = Expression.Lambda<Func<ISparkView>>(exp).Compile();
+ _ctors.Add(type, d);
+
+ return this;
+ }
+
+ public void Unregister(Type type, IViewActivator activator)
+ {
+ }
+
+ public ISparkView Activate(Type type)
+ {
+ return _ctors[type]();
+ }
+
+ public void Release(Type type, ISparkView view)
+ {
+ }
+ }
+}
View
@@ -105,6 +105,7 @@
<Compile Include="Compiler\NodeVisitors\SpecialAttributeVisitorBase.cs" />
<Compile Include="CompositeViewEntry.cs" />
<Compile Include="AbstractSparkView.cs" />
+ <Compile Include="FastViewActivator.cs" />
<Compile Include="ICacheService.cs" />
<Compile Include="ICacheSignal.cs" />
<Compile Include="NullCacheService.cs" />

0 comments on commit 69264e2

Please sign in to comment.