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:
None 
Category:Connector / NET Severity:S5 (Performance)
Version:5.1.4 OS:Any
Assigned to: CPU Architecture:Any

[23 Jan 2008 1:07] 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
[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.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.052 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.