Using AOP / PostSharp to implement a function cache

I just posted this comment on codeproject :

I just discovered this a few hours ago, and I allready wrote a small but very helpfull attribute : a attribute to cache constant but timeconsuming function calls.
If you have a function that takes a lot of time to generate, but the result set is actually the same each time for a certain parameter set, you simply need to define it as follows :
(code is written in VB since we're using vb @ work here)

Module Module1
  Sub Main()
    Console.WriteLine("calling Div2 for i = 1", DoDiv2(1))
    Console.WriteLine("calling Div2 for i = 2", DoDiv2(2))
    Console.WriteLine("calling Div2 for i = 1", DoDiv2(1))
   End Sub

  <Cacheable()> _
  Function DoDiv2(ByVal i As Integer) As Double
     Console.WriteLine("running Dodiv2 for " + i.ToString())
     Return i / 2
  End Function
End Module

If you run this code, you will see that the function only gets executed once for parameter value 1; the second time it just searches the cached dictionary. This avoids having the same code all over the project caching calculated values !!! It is a huge timesaver and makes you code much more maintainable...

The attribute itself was written like this :
Imports ps = PostSharp.Laos

<Serializable()> _
<System.AttributeUsage(AttributeTargets.Method, Inherited:=True, AllowMultiple:=False)> _
Public Class CacheableAttribute
  Inherits ps.OnMethodInvocationAspect

  Shared x As New Hashtable

  Public Overrides Sub OnInvocation(ByVal pEventArgs As PostSharp.Laos.MethodInvocationEventArgs)
    Dim o() As Object = pEventArgs.GetArguments()
    Dim i As Integer = 0, obj As Object
    For Each obj In o
      i += obj.GetHashCode()
    If Not x.Contains(i) Then
      x(i) = pEventArgs.Delegate.DynamicInvoke(o)
    End If
    pEventArgs.ReturnValue = x(i)
  End Sub
End Class

And this in such a short time period. Thanks a lot !!!
BTW(Youve got my 5 on both articles)


comments powered by Disqus