| Bug #34000 | Connection string cache optimization | ||
|---|---|---|---|
| Submitted: | 23 Jan 2008 1:07 | Modified: | 1 Mar 2008 11:19 |
| Reporter: | Maxim Mass | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / NET | Severity: | S5 (Performance) |
| Version: | 5.1.4 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[23 Jan 2008 1:09]
Maxim Mass
Please note that this is part of a series of MySql.Data.DLL optimizations made by MindTouch for open source wiki software Deki Wiki.
[29 Jan 2008 16:32]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/41369
[29 Jan 2008 16:32]
Reggie Burnett
Incorporated into 5.1.5 and 5.2+
[1 Mar 2008 11:19]
MC Brown
A note has been added to the 5.1.5 and 5.2.0 changelog: Incorporated some connection string cache optimizations sent to us by Maxim Mass.

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