home
products
contribute
download
documentation
forum
Home
Forums
New posts
Search forums
What's new
New posts
All posts
Latest activity
Members
Registered members
Current visitors
Donate
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Search titles only
By:
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
MediaPortal 1
Development
General Development (no feature request here!)
Profiling for performance.
Contact us
RSS
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="ojo" data-source="post: 3378" data-attributes="member: 10402"><p>Finally done profiling some....</p><p></p><p>Downloaded the new 0.0.0.10 version before starting out.</p><p></p><p>Here is what i found in at typical run of the unmodified code:</p><p></p><p><strong></strong></p><p> <strong>53,52% MediaPortal.GUI.Library.GUIControlFactory::Create</strong></p><p> <strong>23,69% MediaPortal.GUI.Library.GUIControlFactory::GetString</strong></p><p> <strong>18,91% MediaPortal.GUI.Library.GUIControlFactory::GetInt</strong></p><p><strong> 4,46% MediaPortal.GUI.Library.GUIControlFactory::GetHex</strong></p><p><strong></strong></p><p></p><p>Looking at the code i found that for every GUIControl a whole lot of possible XML-elements are checked and read if present from the skin xml-file. Every time an element was tested it was via the SelectSingleNode method of the standard XML library. Allthough using a subset (a sub-node) this obvious takes a whole lot of processing time.</p><p></p><p>So i spent some time thinking and came up with a possible work-around. Why not cache the XML-elements into a Hashtable using the name of the element as hash. Upon calling the Create method first thing was to cache the elements. Then I changed some (GetString, GetInt, GetHex and GetBool) of the read functions to return from the Hashtable instead of using the SelectSingleNode method.</p><p></p><p>And the results from an equal typical run. The only differences are the changes described above.</p><p></p><p><strong></strong></p><p><strong> 4,14% MediaPortal.GUI.Library.GUIControlFactory::Create</strong></p><p><strong> 0,27% MediaPortal.GUI.Library.GUIControlFactory::GetString</strong></p><p><strong> 0,33% MediaPortal.GUI.Library.GUIControlFactory::GetInt</strong></p><p><strong> 0,21% MediaPortal.GUI.Library.GUIControlFactory::GetHex</strong></p><p><strong></strong></p><p></p><p>No, I didn't believe it either, so a did a second run. But I got approx. same results. </p><p></p><p>And the code:</p><p>[code]</p><p>namespace MediaPortal.GUI.Library</p><p>{</p><p> public class GUIControlFactory</p><p> {</p><p> // just for making this profiling session easier</p><p> private static bool iUseCache = true;</p><p> </p><p> // private cache for holding settings for each control instead of using SelectSingleNode</p><p> // for each possible setting</p><p> private System.Collections.Hashtable XmlCache = new System.Collections.Hashtable(30);</p><p> </p><p> public GUIControlFactory()</p><p> {</p><p> }</p><p></p><p>...</p><p> bool GetString(ref XmlNode RootNode, string strTag, ref string strStringValue)</p><p> {</p><p> if (iUseCache) // profiling</p><p> { </p><p> // new code</p><p> if (!XmlCache.ContainsKey(strTag)) return false;</p><p> string sValue = (string) XmlCache[strTag];</p><p> if (sValue == null) return false;</p><p> if (sValue == "") return false;</p><p> strStringValue = sValue;</p><p> }</p><p> else</p><p> {</p><p> // old code</p><p> XmlNode node = RootNode.SelectSingleNode(strTag);</p><p> if (node == null) return false;</p><p> if (node.InnerText == null) return false;</p><p> if (node.InnerText == "") return false;</p><p> strStringValue = node.InnerText;</p><p> }</p><p> return true;</p><p> }</p><p></p><p>...</p><p> bool GetInt(ref XmlNode RootNode, string strTag, ref int iValue)</p><p> {</p><p> if (iUseCache) // profiling</p><p> { </p><p> // new code</p><p> if (!XmlCache.ContainsKey(strTag)) return false;</p><p> string sValue = (string) XmlCache[strTag];</p><p> if (sValue == null) return false;</p><p> if (sValue == "") return false;</p><p> try</p><p> {</p><p> iValue = System.Int32.Parse(sValue);</p><p> }</p><p> catch (Exception)</p><p> {</p><p> return false;</p><p> }</p><p> }</p><p> else</p><p> {</p><p> // old code</p><p> XmlNode node = RootNode.SelectSingleNode(strTag);</p><p> if (node == null) return false;</p><p> if (node.InnerText == null) return false;</p><p> if (node.InnerText == "") return false;</p><p> try</p><p> {</p><p> iValue = System.Int32.Parse(node.InnerText);</p><p> }</p><p> catch (Exception)</p><p> {</p><p> return false;</p><p> }</p><p> }</p><p> return true;</p><p> }</p><p></p><p></p><p>...</p><p> bool GetHex(ref XmlNode RootNode, string strTag, ref long lValue)</p><p> {</p><p> if (iUseCache) // profiling</p><p> { </p><p> // new code</p><p> if (!XmlCache.ContainsKey(strTag)) return false;</p><p> string sValue = (string) XmlCache[strTag];</p><p> if (sValue == null) return false;</p><p> if (sValue == "") return false;</p><p> try</p><p> {</p><p> lValue = System.Int64.Parse(sValue);</p><p> }</p><p> catch (Exception)</p><p> {</p><p> return false;</p><p> }</p><p> }</p><p> else</p><p> {</p><p> // old code</p><p> XmlNode node = RootNode.SelectSingleNode(strTag);</p><p> if (node == null) return false;</p><p> if (node.InnerText == null) return false;</p><p> if (node.InnerText == "") return false;</p><p> try</p><p> {</p><p> lValue = System.Int64.Parse(node.InnerText, NumberStyles.HexNumber);</p><p> }</p><p> catch (Exception)</p><p> {</p><p> return false;</p><p> }</p><p> }</p><p> return true;</p><p> }</p><p></p><p>...</p><p></p><p> bool GetBoolean(ref XmlNode RootNode, string strTag, ref bool bBoolValue)</p><p> {</p><p> if (iUseCache) // profiling</p><p> { </p><p> // new code</p><p> if (!XmlCache.ContainsKey(strTag)) return false;</p><p> string sValue = (string) XmlCache[strTag];</p><p> if (sValue == null) return false;</p><p> if (sValue == "") return false;</p><p> try</p><p> {</p><p> if (sValue == "off" || sValue == "no" || sValue == "disabled") bBoolValue = false;</p><p> else bBoolValue = true;</p><p> }</p><p> catch (Exception)</p><p> {</p><p> return false;</p><p> }</p><p> }</p><p> else</p><p> {</p><p> // old code</p><p> XmlNode node = RootNode.SelectSingleNode(strTag);</p><p> if (node == null) return false;</p><p> if (node.InnerText == null) return false;</p><p> if (node.InnerText == "") return false;</p><p> </p><p> string strEnabled = node.InnerText;</p><p> if (strEnabled == "off" || strEnabled == "no" || strEnabled == "disabled") bBoolValue = false;</p><p> else bBoolValue = true;</p><p> }</p><p> return true;</p><p> }</p><p></p><p>...</p><p></p><p>[/code]</p><p></p><p>The same can be used for the other Get'ters as well. GetAlignment, GetLong etc. I only did the most time consuming to prove the concept.</p><p></p><p>Ojo</p></blockquote><p></p>
[QUOTE="ojo, post: 3378, member: 10402"] Finally done profiling some.... Downloaded the new 0.0.0.10 version before starting out. Here is what i found in at typical run of the unmodified code: [b] 53,52% MediaPortal.GUI.Library.GUIControlFactory::Create 23,69% MediaPortal.GUI.Library.GUIControlFactory::GetString 18,91% MediaPortal.GUI.Library.GUIControlFactory::GetInt 4,46% MediaPortal.GUI.Library.GUIControlFactory::GetHex [/b] Looking at the code i found that for every GUIControl a whole lot of possible XML-elements are checked and read if present from the skin xml-file. Every time an element was tested it was via the SelectSingleNode method of the standard XML library. Allthough using a subset (a sub-node) this obvious takes a whole lot of processing time. So i spent some time thinking and came up with a possible work-around. Why not cache the XML-elements into a Hashtable using the name of the element as hash. Upon calling the Create method first thing was to cache the elements. Then I changed some (GetString, GetInt, GetHex and GetBool) of the read functions to return from the Hashtable instead of using the SelectSingleNode method. And the results from an equal typical run. The only differences are the changes described above. [b] 4,14% MediaPortal.GUI.Library.GUIControlFactory::Create 0,27% MediaPortal.GUI.Library.GUIControlFactory::GetString 0,33% MediaPortal.GUI.Library.GUIControlFactory::GetInt 0,21% MediaPortal.GUI.Library.GUIControlFactory::GetHex [/b] No, I didn't believe it either, so a did a second run. But I got approx. same results. And the code: [code] namespace MediaPortal.GUI.Library { public class GUIControlFactory { // just for making this profiling session easier private static bool iUseCache = true; // private cache for holding settings for each control instead of using SelectSingleNode // for each possible setting private System.Collections.Hashtable XmlCache = new System.Collections.Hashtable(30); public GUIControlFactory() { } ... bool GetString(ref XmlNode RootNode, string strTag, ref string strStringValue) { if (iUseCache) // profiling { // new code if (!XmlCache.ContainsKey(strTag)) return false; string sValue = (string) XmlCache[strTag]; if (sValue == null) return false; if (sValue == "") return false; strStringValue = sValue; } else { // old code XmlNode node = RootNode.SelectSingleNode(strTag); if (node == null) return false; if (node.InnerText == null) return false; if (node.InnerText == "") return false; strStringValue = node.InnerText; } return true; } ... bool GetInt(ref XmlNode RootNode, string strTag, ref int iValue) { if (iUseCache) // profiling { // new code if (!XmlCache.ContainsKey(strTag)) return false; string sValue = (string) XmlCache[strTag]; if (sValue == null) return false; if (sValue == "") return false; try { iValue = System.Int32.Parse(sValue); } catch (Exception) { return false; } } else { // old code XmlNode node = RootNode.SelectSingleNode(strTag); if (node == null) return false; if (node.InnerText == null) return false; if (node.InnerText == "") return false; try { iValue = System.Int32.Parse(node.InnerText); } catch (Exception) { return false; } } return true; } ... bool GetHex(ref XmlNode RootNode, string strTag, ref long lValue) { if (iUseCache) // profiling { // new code if (!XmlCache.ContainsKey(strTag)) return false; string sValue = (string) XmlCache[strTag]; if (sValue == null) return false; if (sValue == "") return false; try { lValue = System.Int64.Parse(sValue); } catch (Exception) { return false; } } else { // old code XmlNode node = RootNode.SelectSingleNode(strTag); if (node == null) return false; if (node.InnerText == null) return false; if (node.InnerText == "") return false; try { lValue = System.Int64.Parse(node.InnerText, NumberStyles.HexNumber); } catch (Exception) { return false; } } return true; } ... bool GetBoolean(ref XmlNode RootNode, string strTag, ref bool bBoolValue) { if (iUseCache) // profiling { // new code if (!XmlCache.ContainsKey(strTag)) return false; string sValue = (string) XmlCache[strTag]; if (sValue == null) return false; if (sValue == "") return false; try { if (sValue == "off" || sValue == "no" || sValue == "disabled") bBoolValue = false; else bBoolValue = true; } catch (Exception) { return false; } } else { // old code XmlNode node = RootNode.SelectSingleNode(strTag); if (node == null) return false; if (node.InnerText == null) return false; if (node.InnerText == "") return false; string strEnabled = node.InnerText; if (strEnabled == "off" || strEnabled == "no" || strEnabled == "disabled") bBoolValue = false; else bBoolValue = true; } return true; } ... [/code] The same can be used for the other Get'ters as well. GetAlignment, GetLong etc. I only did the most time consuming to prove the concept. Ojo [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
MediaPortal 1
Development
General Development (no feature request here!)
Profiling for performance.
Contact us
RSS
Top
Bottom