I was able to make a HUGE difference in performance by caching the database instance it creates in the constructor/init procedures. What I am seeing now is ~2-3x speed up, depending on the situation and the run.
1) The method of just replacing _db with a static instance works fine if you only call the default constructor, and has all the same speed benefits.
// MyProject.MyDB _db;
// replace with a static instance, and remove the "this." from other lines
static MyProject.MyDB _db = new MyDB();
public MyClass() {
//_db=new MyProject.MyDB();
Init();
}
2) I have written a little caching class for the DB entries and am calling that from my ActiveRecord.tt file in all the old places where "new()" was used.
// REPLACE "MyDB" with the name of your DB. Alternately, include this
// class in Context.tt and have it generate the correct name.
class ContextDatabaseCache {
public static MyDB GetMyDB()
{
return GetInstance("~~default~~", () => new MyDB());
}
public static MyDB GetMyDB(string connectionString) {
return GetInstance(connectionString, () => new MyDB(connectionString));
}
public static MyDB GetMyDB(string connectionString, string providerName)
{
return GetInstance(connectionString + providerName, () => new MyDB(connectionString, providerName));
}
private static Dictionary<string, MyDB> _dict = new Dictionary<string, MyDB>();
private static MyDB GetInstance(string key, Func<MyDB> createInstance)
{
if (!_dict.ContainsKey(key)) {
lock (_dict) {
if (!_dict.ContainsKey(key)) {
_dict.Add(key, createInstance());
}
}
}
return _dict[key];
}
///<summary>Call this when the "DefaultConnection" string changes in the
/// App.exe.config file so that a new db instance will be created
/// and pick up the changed value. </summary>
public static void Clear() {
_dict.Clear();
}
}
This is the type of replacement that was made in the ActiveRecord.tt file:
public <#=tbl.ClassName#>(){
_db=new <#=Namespace#>.<#=DatabaseName#>DB();
Init();
}
// becomes this:
public <#=tbl.ClassName#>(){
_db= <#=Namespace#>.ContextDatabaseCache.Get<#=DatabaseName#>DB();
Init();
}