Description:
Retrieving the MySqlConnectionStringBuilder object from connection string cache currently
incurs an unnecessary overhead of performing a lookup in a NameObjectCollection. Even when
there is only one item in the cache there's roughly .5ms of overhead which becomes
noticeable as this is done very often in a db dependent app.
Another connection string related optimization is in MySqlConnectionStringBuilder.Clear()
How to repeat:
Make repeated db calls and look at
Void MySql.Data.MySqlClient.MySqlConnection.set_ConnectionString(String)
with a profiler.
Suggested fix:
Replace the MySql.Data.Common.Cache class with the following which uses a dictionary
instead but still removes connection string when filled to capacity.
MySql.Data.Common.Cache:
private int _capacity;
private Queue<KeyType> _keyQ;
private Dictionary<KeyType, ValueType> _contents;
public Cache(int initialCapacity, int capacity) {
_capacity = capacity;
_contents = new Dictionary<KeyType, ValueType>(initialCapacity);
if (capacity > 0) {
_keyQ = new Queue<KeyType>(initialCapacity);
}
}
public ValueType this[KeyType key] {
get {
ValueType val;
if (_contents.TryGetValue(key, out val))
return val;
else
return default(ValueType);
}
set { InternalAdd(key, value); }
}
public void Add(KeyType key, ValueType value) {
InternalAdd(key, value);
}
private void InternalAdd(KeyType key, ValueType value) {
if (!_contents.ContainsKey(key)) {
if (_capacity > 0) {
_keyQ.Enqueue(key);
if (_keyQ.Count > _capacity) {
_contents.Remove(_keyQ.Dequeue());
}
}
}
_contents[key] = value;
}
}
MySqlConnectionStringBuilder.Clear():
Change
foreach (Keyword k in defaultValues.Keys)
SetValue(k, defaultValues[k]);
TO:
foreach (KeyValuePair<Keyword, object> k in defaultValues)
SetValue(k.Key, k.Value);
to avoid unnecessary dictionary lookups
Description: Retrieving the MySqlConnectionStringBuilder object from connection string cache currently incurs an unnecessary overhead of performing a lookup in a NameObjectCollection. Even when there is only one item in the cache there's roughly .5ms of overhead which becomes noticeable as this is done very often in a db dependent app. Another connection string related optimization is in MySqlConnectionStringBuilder.Clear() How to repeat: Make repeated db calls and look at Void MySql.Data.MySqlClient.MySqlConnection.set_ConnectionString(String) with a profiler. Suggested fix: Replace the MySql.Data.Common.Cache class with the following which uses a dictionary instead but still removes connection string when filled to capacity. MySql.Data.Common.Cache: private int _capacity; private Queue<KeyType> _keyQ; private Dictionary<KeyType, ValueType> _contents; public Cache(int initialCapacity, int capacity) { _capacity = capacity; _contents = new Dictionary<KeyType, ValueType>(initialCapacity); if (capacity > 0) { _keyQ = new Queue<KeyType>(initialCapacity); } } public ValueType this[KeyType key] { get { ValueType val; if (_contents.TryGetValue(key, out val)) return val; else return default(ValueType); } set { InternalAdd(key, value); } } public void Add(KeyType key, ValueType value) { InternalAdd(key, value); } private void InternalAdd(KeyType key, ValueType value) { if (!_contents.ContainsKey(key)) { if (_capacity > 0) { _keyQ.Enqueue(key); if (_keyQ.Count > _capacity) { _contents.Remove(_keyQ.Dequeue()); } } } _contents[key] = value; } } MySqlConnectionStringBuilder.Clear(): Change foreach (Keyword k in defaultValues.Keys) SetValue(k, defaultValues[k]); TO: foreach (KeyValuePair<Keyword, object> k in defaultValues) SetValue(k.Key, k.Value); to avoid unnecessary dictionary lookups