性能调优(一) 缓存方法返回值

对于多次调用且耗时比较长的方法,在第一次调用时,把“返回值”保存起来,在以后再次调用时,直接返回“返回值”。

 

案例:在客户代码中,多次调用方法ExecuteStoredProcedure,且传入的参数相同。

 

 
  
class Program
{
static void Main( string [] args)
{
int total = 0 ;

DBAccess db
= new DBAccess();
for ( int i = 0 ; i < 100 ; i ++ )
{
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i });
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i + 1 });
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i + 2 });
}

Console.WriteLine(total);
}
}

class DBAccess
{
public int ExecuteStoredProcedure( string spName, object [] parameters)
{
// 在此要访问数据库,运行时间较长
// ...

System.Threading.Thread.Sleep(
100 );
return 2010 ;
}
}

 

 

此案例的性能调优方法:

 

 
  
class Program
{
static void Main( string [] args)
{
int total = 0 ;

DBAccess db
= new DBAccessEx();
for ( int i = 0 ; i < 100 ; i ++ )
{
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i });
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i + 1 });
total
+= db.ExecuteStoredProcedure( " sp1 " , new object [] { i + 2 });
}

Console.WriteLine(total);

Console.Read();
}
}

class DBAccess
{
public virtual int ExecuteStoredProcedure( string spName, object [] parameters)
{
// 在此要访问数据库,运行时间较长
// ...

System.Threading.Thread.Sleep(
100 );
return 2010 ;
}
}

class DBAccessEx : DBAccess
{
MethodInvoker invoker
= null;
DBAccess delegateObj
= null;

public DBAccessEx()
{
delegateObj
= new DBAccess();
invoker
= new MethodInvoker(delegateObj);
}

public override int ExecuteStoredProcedure(string spName, object[] parameters)
{
return (int)this.invoker.Invoke(
"ExecuteStoredProcedure",
new object[] { spName, parameters });
}
}

 

 

辅助类:

 

代码
 
   
public class MethodInvoker
{
private readonly Dictionary < Key, object > ResultDictionary = new Dictionary < Key, object > ();
private object _instance;
private Type _type;

public MethodInvoker( object instance)
{
this ._instance = instance;
this ._type = this ._instance.GetType();
}

public object Invoke( string methodName, object [] parameters, Type[] parameterTypes)
{
if ( string .IsNullOrEmpty(methodName)) throw new ArgumentNullException( " methodName " );
if (parameters == null ) throw new ArgumentNullException( " parameters " );

object result;
if (Find(methodName, parameters, out result))
return result;

MethodInfo methodInfo
= _type.GetMethod(methodName, parameterTypes);
if (methodInfo == null ) throw new MethodNotFundException();
result
= methodInfo.Invoke(_instance, parameters);

Cache(methodName, parameters, result);

return result;
}

public object Invoke( string methodName, object [] parameters)
{
if ( string .IsNullOrEmpty(methodName)) throw new ArgumentNullException( " methodName " );
if (parameters == null ) throw new ArgumentNullException( " parameters " );

object result;
if (Find(methodName, parameters, out result))
return result;

MethodInfo methodInfo
= _type.GetMethod(methodName);
if (methodInfo == null ) throw new MethodNotFundException();
result
= methodInfo.Invoke(_instance, parameters);

Cache(methodName, parameters, result);

return result;
}

public void RemoveCache()
{
ResultDictionary.Clear();
}

private bool Find( string methodName, object [] parameters, out object result)
{
var key
= new Key(methodName, parameters);
if (ResultDictionary.ContainsKey(key))
{
result
= ResultDictionary[key];
return true ;
}
else
{
result
= null ;
return false ;
}
}

private void Cache( string methodName, object [] parameters, object result)
{
var key
= new Key(methodName, parameters);
ResultDictionary.Add(key, result);
}


[Serializable]
class Key
{
private string _methodName;
private object [] _parameters;

public Key( string methodName, object [] parameters)
{
this ._methodName = methodName;
this ._parameters = parameters;
}

public string MethodName
{
get { return _methodName; }
}

public override bool Equals( object obj)
{
if (obj is Key)
{
Key c
= obj as Key;

if ( ! MethodName.Equals(c.MethodName))
return false ;

if ( ! _parameters.Length.Equals(c._parameters.Length))
return false ;

MemoryStream stream1
= GetMemoryStream( this ._parameters);
MemoryStream stream2
= GetMemoryStream(c._parameters);
bool isMemoryEqual = MemoryStreamEquals(stream1, stream2);
stream1.Close();
stream2.Close();

if ( ! isMemoryEqual) return false ;

return true ;
}
else
{
return false ;
}
}

public override int GetHashCode()
{
int hashCode = 0 ;
hashCode
+= this .MethodName.GetHashCode();
// hashCode += this.Instance.GetHashCode();
// hashCode += this._parameters.Length;
// foreach (var parameter in _parameters)
// {
// if (parameter != null)
// hashCode += parameter.GetHashCode();
// }
return hashCode;
}

private static MemoryStream GetMemoryStream( object p)
{
MemoryStream memStream
= new MemoryStream();
BinaryFormatter binFormatter
= new BinaryFormatter();
binFormatter.Serialize(memStream, p);

return memStream;
}

private static bool MemoryStreamEquals(MemoryStream stream1, MemoryStream stream2)
{
if (stream1.Length != stream2.Length)
return false ;

for ( int i = 0 ; i < stream1.Length; i ++ )
{
stream1.Seek(i, SeekOrigin.Begin);
stream2.Seek(i, SeekOrigin.Begin);

int x = stream1.ReadByte();
int y = stream2.ReadByte();

if (x != y) return false ;
}

return true ;
}

}
}

public class MethodNotFundException : Exception
{
}

 

 

此性能调优方法有不妥之处,敬请指正。如果你有其他优化方案,能不能分享一下,^_^ 谢了先。

转载于:https://www.cnblogs.com/JiangJihua/archive/2010/10/21/1857511.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值