PDA

View Full Version : [CLOSED] Question about performance



Multysh
Sep 29, 2014, 12:31 PM
Example code:


protected void Page_Load(object sender, EventArgs e)
{
var n = 100;
var sw = Stopwatch.StartNew();
var sb = new StringBuilder();
for (int i = 0; i < n; i++)
{
var mi = new MenuItem("Some text in MI " + i);
mi.DirectEvents.Click.Url = "/Myurl";
mi.DirectEvents.Click.ExtraParams.Add(new Parameter("p1", "nn" + Guid.NewGuid()));

var cfg = mi.ToConfig();
sb.Append(cfg);
sb.Append(",");
}

sw.Stop();
var result = string.Format("N:{1} Avg:{0} Time:{2} ",sw.Elapsed.TotalMilliseconds / n, n, sw.Elapsed.TotalMilliseconds);
var fn= typeof(MenuItem).Assembly.FullName;

form1.Controls.Add(new System.Web.UI.WebControls.Label() { Text = fn+ "<br/>" + result });
}

fairly simple js:


{
id: "id626c18b1703505f0",
xtype: "menuitem",
text: "Some text in MI 0",
directEvents: {
click: {
fn: function(item, e) {
Ext.net.directRequest({
cleanRequest: true,
url: "/Myurl",
extraParams: {
"p1": "nn8ef994ea-63ce-42e0-9fde-9b885c185391"
},
control: this
});
}
}
}
}

Timings on different Ext.NET versions (on not very slow core i7-2600):

Ext.Net, Version=1.2.0.19755, Culture=neutral, PublicKeyToken=2e12ce3d0176cd87
N:100 Avg:0,408164 Time:40,8164

Ext.Net, Version=1.7.0.0, Culture=neutral, PublicKeyToken=2e12ce3d0176cd87
N:100 Avg:0,401263 Time:40,1263

Ext.Net, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2e12ce3d0176cd87
N:100 Avg:0,683862 Time:68,3862

Ext.Net, Version=2.5.2.10697, Culture=neutral, PublicKeyToken=2e12ce3d0176cd87
N:100 Avg:0,797429 Time:79,7429

Serialization of equialent object is much faster (10-100 times).
Is there any ways to increase performance of ToConfig?
What causes such a drawdown performance?

Daniil
Sep 29, 2014, 2:57 PM
Hi @Multysh,

Welcome to the Ext.NET forums!

Thank you for the investigation.

There are, probably, a few reasons with different contributions. Since Ext.NET v1 the following happened with v2:

- The logic of the ToConfig method has been change/extended.
- The Ext.NET components have more config options.
- There is another version of Newtonsoft.Json.dll.
- Maybe, something else.

I imagine that it might be very difficult to determine exact weight of each reason in that regression. Though, is it really worth to put efforts into the further investigation? Yes, 40 ms VS 80 ms, but it is milliseconds... I would also say that the ToConfig method is not supposed to be called often. Actually, it is an advice for you how to improve the performance. You can put all the MenuItems into a Menu and call .ToConfig() once on that Menu. It should work faster.

Multysh
Sep 30, 2014, 11:49 AM
Could you provide example of Best Practice for creating dynamic menu?
Menu must be created after click on button. (it depends on seletion in grid, or form content or something else).

In the example below there are two methods - AddItems uses ExtNET features to create javascript, it takes about 50 ms for create pretty simple JSON. Another method AddItemsJSON it creates similar object and serializes it to JSON. It takes about 0.5 ms.

Ok, ExtNET is not just simple serialization util, but it takes 100 (one hundred) times more time than serialization.

Is it possible to generate 100-Items-Menu creation script for about 5 ms? (10 times slower than serialization)

Example:


<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="Newtonsoft.Json" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void AddItems(object sender, DirectEventArgs e)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < 100; i++)
{
Ext.Net.MenuItem mi1 = new Ext.Net.MenuItem("New item " + i);
mi1.DirectEvents.Click.Url = "/SomeUrl";
mi1.DirectEvents.Click.ExtraParams.Add(new Ext.Net.Parameter("p1", "val"));
this.Menu1.Items.Add(mi1);
mi1.Render();
}

sw.Stop();
Response.Headers.Add("TimeToGen", sw.Elapsed.TotalMilliseconds.ToString());
}
protected void AddItemsJSON(object sender, DirectEventArgs e)
{
var sw = Stopwatch.StartNew();
var sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
var mi = new
{
Menu = new
{
id = "id" + Guid.NewGuid().ToString().Substring(0, 5),
text = "New item " + i,
directEvents = new
{
click = new
{
DirectRequest = new
{
Function = "ololo",
parameters = new[]
{
"par1", "par2"
},
}
}
}
}
};
var tx = JsonConvert.SerializeObject(mi);
sb.Append(tx);
}

sw.Stop();
Response.Headers.Add("TimeToGen", sw.Elapsed.TotalMilliseconds.ToString());
}
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.NET Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:Button runat="server" Text="Menu" OnDirectClick="AddItems">
<Menu>
<ext:Menu ID="Menu1" runat="server">
<Listeners>
<BeforeShow Fn="function(){this.items.clear(); console.log(new Date().toISOString());}"></BeforeShow>
</Listeners><Listeners>
<AfterLayout Fn="function(){console.log('Click After' + new Date().toISOString());}">
</AfterLayout>
</Listeners>
<Items>
<ext:MenuItem runat="server" Text="Item 1" />
</Items>
</ext:Menu>
</Menu>
</ext:Button>
<ext:Button runat="server" Text="Add items" OnDirectClick="AddItems" />
</body>
</html>

Daniil
Sep 30, 2014, 2:55 PM
A .Render() call renders the control, not just serializes it. It involves creating a proxy page control, because rendering of the control requires some context. Also it runs the control life cycle. So, we would not compare rendering and serialization.

As for best practices, I would load menu items like this.

Example

<%@ Page Language="C#" %>

<script runat="server">
[DirectMethod]
public static object GetMenuItems(Dictionary<string,string> extraParams)
{
List<AbstractComponent> components = new List<AbstractComponent>();
string prefix = extraParams["someParam"];

for (int i = 0; i < 100; i++)
{
Ext.Net.MenuItem mi = new Ext.Net.MenuItem(prefix + "Item " + i);
mi.Listeners.Click.Handler = "alert(this.text)";
components.Add(mi);
}

return ComponentLoader.ToConfig(components);
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:Button runat="server" Text="Menu">
<Menu>
<ext:Menu runat="server" MinHeight="100">
<Loader
runat="server"
Mode="Component"
DirectMethod="App.direct.GetMenuItems"
RemoveAll="true">
<Params>
<ext:Parameter Name="someParam" Value="SomePrefix_" Mode="Value" />
</Params>
<LoadMask ShowMask="true" />
</Loader>
<Items>
<ext:MenuItem runat="server" />
</Items>
</ext:Menu>
</Menu>
</ext:Button>
</body>
</html>