对于多次调用且耗时比较长的方法,在第一次调用时,把“返回值”保存起来,在以后再次调用时,直接返回“返回值”。
案例:在客户代码中,多次调用方法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 ;
}
}
{
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 });
}
}
{
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 });
}
}
辅助类:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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
{
}
{
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
{
}
此性能调优方法有不妥之处,敬请指正。如果你有其他优化方案,能不能分享一下,^_^ 谢了先。