Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Wednesday, November 23, 2022

Slow VMWare Player after upgrade to Windows 11

Recently my Windows 10 PC was upgraded to Windows 11. One problem which I noticed after that was slowness of VMWare Player on Windows 11 comparing with Windows 10. There are several posts about similar problem which may be found in internet - almost all of them suggest few things: turn off Hyper-V Windows feature, run command "bcdedit /set hypervisorlaunchtype off", disable memory integrity in Windows Security > Device Security > Core Isolation details. I tried them but it didn't help.

I also tried to update to the latest VMWare Player 17 which according to it's description fully supports Windows 11 as host operating system. That didn't help either.

Also some posts suggested obvious things like increasing memory and CPU. I tried to increase memory a bit (virtual machine already had 16Gb RAM and 8 processor cores which should be enough. Remember that on Windows 10 it worked very fast) without success.

Then I tried opposite thing: reduce number of processor cores from 8 to 4:

and surprisingly it helped! VMWare Player became fast again. This solution may look non logical but may help someone so I decided to share it.

Friday, January 21, 2022

CosmosDB: compare queries performance against strings and array properties

Imagine that we have CosmosDB instance running in Azure (created with SQL syntax enabled) which has groups entities. Each group has members property - JSON array of members of this group. Also each group has the same members serialized to string in membersStr property:

{
    "id": "cf66e4ea-39b6-43bf-a237-8ae997c8cd6a",
    "membersStr": "[{\"loginName\":\"user.automatic17@mytenant.onmicrosoft.com\",\"displayName\":\"User Automatic17\",\"id\":\"53bcf941-fa64-4af2-ac47-c7f48430df29\"},{\"loginName\":\"user.automatic52@mytenant.onmicrosoft.com\",\"displayName\":\"User Automatic52\",\"msGraphUserId\":\"515ee5ae-71dc-4c5a-a844-41af5f9d419c\"},{\"loginName\":\"user.automatic67@mytenant.onmicrosoft.com\",\"displayName\":\"User Automatic67\",\"msGraphUserId\":\"21106ae1-25fb-43ac-a5e5-aa1f0d3f9f2f\"}]",
    "members": [{
        "loginName": "user.automatic17@mytenant.onmicrosoft.com",
        "displayName": "User Automatic17",
        "id": "53bcf941-fa64-4af2-ac47-c7f48430df29"
    }, {
        "loginName": "user.automatic52@mytenant.onmicrosoft.com",
        "displayName": "User Automatic52",
        "msGraphUserId": "515ee5ae-71dc-4c5a-a844-41af5f9d419c"
    }, {
        "loginName": "user.automatic67@mytenant.onmicrosoft.com",
        "displayName": "User Automatic67",
        "msGraphUserId": "21106ae1-25fb-43ac-a5e5-aa1f0d3f9f2f"
    }]
	...
}

The question which we wanted to clarify is if we want to get groups where specific user is member - what query will be faster:

1. which uses membersStr property and LIKE operator:

SELECT c FROM c WHERE c.membersStr LIKE '%{userId}%'

2. or which uses array and object-oriented query against members properties:

SELECT c FROM c JOIN m IN c.members WHERE m.id = '{userId}'

For running this test I used CosmosDB with 10K entities with random users data. For testing I used the following C# methods:

private static List<object> GetGroupsByArray(string userId)
{
    string query = $"SELECT c FROM c JOIN m IN c.members WHERE m.id = '{userId}'";
    QueryDefinition queryDefinition = new QueryDefinition(query);
    var groupsContainer = cosmosClient.GetContainer(DBName, ContainerName);
    FeedIterator<object> queryResultSetIterator = groupsContainer.GetItemQueryIterator<object>(queryDefinition);
    var groups = new List<object>();
    while (queryResultSetIterator.HasMoreResults)
    {
        FeedResponse<object> currentResultSet = queryResultSetIterator.ReadNextAsync().GetAwaiter().GetResult();
        foreach (var group in currentResultSet)
        {
            groups.Add(group);
        }
    }

    return groups;
}

private static List<object> GetGroupsByString(string userId)
{
    string query = $"SELECT c FROM c WHERE c.membersStr LIKE '%{userId}%'";
    QueryDefinition queryDefinition = new QueryDefinition(query);
    var groupsContainer = cosmosClient.GetContainer(DBName, ContainerName);
    FeedIterator<object> queryResultSetIterator = groupsContainer.GetItemQueryIterator<object>(queryDefinition);
    var groups = new List<object>();
    while (queryResultSetIterator.HasMoreResults)
    {
        FeedResponse<object> currentResultSet = queryResultSetIterator.ReadNextAsync().GetAwaiter().GetResult();
        foreach (var group in currentResultSet)
        {
            groups.Add(group);
        }
    }

    return groups;
}

Each method was called with 10 random user ids. In both cases time of query depended from number of groups user belongs to (the more groups user was member of the more time query took). I made 10 test runs of both methods and measured execution time with System.Diagnostics.Stopwatch. Then I calculated average execution time for each run of 1st method and separately for 2nd method. Finally I measured average execution time for all 10 test runs.

Result was that query against string property (JSON-serialized array) was a bit faster (929.53 milliseconds) than query agianst array property (1362.3). Conclusion is that if performance is not critical for you and you want to have nice-looking entities in CosmosDB you may use array properties. But if performance is critical you may consider to use JSON-serialized property (or use both as an option).

Update 2022-04-14: we also compared internal query engine execution time and got different results. For array-based approach performance was better. For string-based approach query took 38ms:

while for array-based approach only 18ms:

Probably .Net SDK which was used during 1st test added own delays. Consider that when you will choose approach for your scenario.

Friday, January 24, 2020

How to set Always On for Azure Function app via PowerShell

If you run Azure functions on dedicated App service plan (vs Consumption plan) of Basic pricing tier and above you may speed up warmup time of Azure functions by enabling Always On setting (Azure Function app > Configuration > General settings):

If you need to automate this process here is the PowerShell script which can be used in order to set Always On for Azure Function app:

$resourceGroupName = ...
$functionAppName = ...
$webAppPropertiesObject = @{"siteConfig" = @{"AlwaysOn" = $true}}
$webAppResource = Get-AzureRmResource -ResourceType "microsoft.web/sites" -ResourceGroupName $resourceGroupName -ResourceName $functionAppName
$webAppResource | Set-AzureRmResource -PropertyObject $webAppPropertiesObject -Force

After that you Function app will have Always On setting enabled.

Thursday, July 19, 2012

Create asynchronous web parts for Sharepoint

One of the way to improve performance of your Sharepoint site is to implement custom web parts via ajax. As you probably know there are standard Sharepoint web parts which support ajax out of the box. E.g. Search core results web part has Ajax options in properties:

image

If you will check “Enable Asynchronous Load” option, web part will be loaded asynchronously and won’t block page loading. But not all standard web parts have this possibility. Custom web parts by default also are not ajax enabled. You need to do additional work in order to implement them asynchronously.

In this post I will show how to create async custom web part using “Framework for loading SharePoint web parts asynchronously” from Codeplex (thanks to author Chaitu Madala for sharing it). There are other ways to do that, but I decided to use this project as it is more or less good extendable and can be reused for many custom web parts in your solution. Basic idea is shown in the following schema:

image

Let’s begin from custom web part class. It should inherit BaseWebPart class from async framework project (BaseWebPart in turn inherits regular ASP.Net WebPart class). BaseWebPart contains 2 methods: one for creating container for progress indicator, another for registering asynchronous web service proxy. Simplified version looks like this:

   1: public class BaseWebPart : WebPart
   2: {
   3:     protected Panel contentContainer;
   4:  
   5:     protected void PrepareContentContainer()
   6:     {
   7:         try
   8:         {
   9:             if (HttpContext.Current.Request.Browser.EcmaScriptVersion.Major >= 1)
  10:             {
  11:                 //Busy Box View (JS enabled)
  12:                 Image spinnerImage = new Image();
  13:                 spinnerImage.ImageUrl = String.Format("{0}{1}",
  14: SPContext.Current.Web.Url, "/_layouts/AsyncWebpart/Images/loadingspinner.gif");
  15:                 Label spinnerText = new Label()
  16: { Text = "Please wait while the results are being loaded.." };
  17:  
  18:                 contentContainer.ID = "" + this.ID + "Context";
  19:                 contentContainer.Controls.Add(spinnerImage);
  20:                 contentContainer.Controls.Add(new LiteralControl("<br />"));
  21:                 contentContainer.Controls.Add(spinnerText);
  22:                 //AJAX Enabled
  23:             }
  24:             else
  25:             {
  26:                 //AJAX Disabled - Fallback mode
  27:                  //Alternative content in case the user's browser does not support JS
  28:                 contentContainer.Controls.Add(
  29: new LiteralControl("It seems your browser doesn't support Javascript"));
  30:             }
  31:         }
  32:         catch (Exception ex)
  33:         {
  34:             // log
  35:         }
  36:     }
  37:  
  38:     protected void AddScriptManagerReferenceProxy(string referenceProxyUrl,
  39: string referenceProxyJS)
  40:     {
  41:         try
  42:         {
  43:             ScriptManager thisScriptManager = ScriptManager.GetCurrent(this.Page);
  44:             if (thisScriptManager == null)
  45:             {
  46:                 thisScriptManager = new ScriptManager();
  47:                 this.Controls.Add(thisScriptManager);
  48:             }
  49:  
  50:             ServiceReference referenceProxy = new ServiceReference();
  51:             referenceProxy.Path = referenceProxyUrl;
  52:  
  53:             referenceProxy.InlineScript = true;
  54:             //If you are having issues identifying the names of the web service JS methods, uncomment the line above ^
  55:  
  56:             thisScriptManager.Services.Add(referenceProxy);
  57:  
  58:             //JS file contains proxy methods for web service - see file for details
  59:  
  60:             this.Page.ClientScript.RegisterClientScriptInclude(typeof(Page), referenceProxyUrl, referenceProxyJS);
  61:         }
  62:         catch (Exception ex)
  63:         {
  64:             // log
  65:         }
  66:     }
  67: }

Web service will be described below. Here it is important to understand that we registered async proxy which can be called from javascript.

For this article let’s create simple custom web part with single custom property Delay. It contains delay in seconds which web service will wait until return response to the client. Those we will simulate long running operation. The code of web part will look like this:

   1: public class AsyncCustomWebPart : BaseWebPart
   2: {
   3:     [WebBrowsable(true)]
   4:     [Personalizable(PersonalizationScope.Shared)]
   5:     public int Delay { get; set; }
   6:  
   7:     protected override void OnLoad(EventArgs e)
   8:     {
   9:         try
  10:         {
  11:             EnsureChildControls();
  12:  
  13:             // register script to automatically load the web part into the content container
  14:             // pass all the property values through asynchronous call
  15:             this.Page.ClientScript.RegisterStartupScript(typeof (Page),
  16:                 "startupScript" + this.ClientID,
  17:                 string.Format("AsyncWebPartGetData('{0}', '{1}');",
  18:                     this.Delay, contentContainer.ClientID), true);
  19:  
  20:             base.OnLoad(e);
  21:         }
  22:         catch (Exception ex)
  23:         {
  24:             // handle error
  25:         }
  26:     }
  27:  
  28:     protected override void CreateChildControls()
  29:     {
  30:         try
  31:         {
  32:             contentContainer = new Panel();
  33:  
  34:             // prepare container to hold the content
  35:             PrepareContentContainer();
  36:             // add web service reference and js handler
  37:             AddScriptManagerReferenceProxy(
  38:                 "/_layouts/AsyncWebPart/AsyncWebPartService.asmx",
  39:                 "/_layouts/AsyncWebPart/JS/AsyncWebPart.js");
  40:         }
  41:         catch (Exception ex)
  42:         {
  43:             // handle error
  44:         }
  45:     }
  46:  
  47:     public override void RenderControl(HtmlTextWriter writer)
  48:     {
  49:         contentContainer.RenderControl(writer);
  50:         base.RenderControl(writer);
  51:     }
  52: }

Here in OnLoad method we ensure that child controls are created (line 11). In CreateChildControls method (lines 28-45) we create Panel control which will be actual container into which we will load html from web service. As we already saw in PrepareContentContainer method (line 35) we load animated gif which shows progress indicator on the page until web part content won’t be ready:

image

After that we add async web service proxy and reference to the AsyncWebPart.js file which is part of the async web parts framework (lines 37-39). I will show content of this javascript file below.

Then in OnLoad method we register javascript startup script for our custom function AsyncWebPartGetData which is defined in AsyncWebPart.js and pass all custom web part properties into this function. These properties will be then passed to the web service. I.e. we will still have possibility to change web part behavior via its properties even for asynchronous version.

Ok, what happens next? When page is loaded our javascript function is called. Let’s see the code of AsyncWebPart.js:

   1: function AsyncWebPartGetData(delay, containerID) 
   2: {
   3:     //Remember to use entire namespace + class before method name
   4:     AsyncWebPart.AsyncWebPartService.GetUIHtmlForAsyncWebPart(
   5:         delay, AsyncWebPartComplete, AsyncWebPartError, containerID);
   6: }
   7:  
   8: //Client-side onComplete handler
   9: function AsyncWebPartComplete(response, containerID) 
  10: {
  11:     //Populates the container with the response
  12:     var containerDiv = document.getElementById(containerID);
  13:     containerDiv.innerHTML = response;
  14: }
  15:  
  16: //Client-side onError handler
  17: function AsyncWebPartError(response, containerID) 
  18: {
  19:     var containerDiv = document.getElementById(containerID);
  20:     containerDiv.innerHTML = "An error has occurred. Please contact administrator.";
  21: }

AsyncWebPartGetData function is unique for our custom web part. I.e. if you will need to make another web part asynchronously, you need to create another function for it. Two other methods (AsyncWebPartComplete and AsyncWebPartError) can be reused for all web parts. AsyncWebPartGetData receives all custom web part properties as parameters. In our example it is delay and containerID (containerID should be passed to all another functions for other web parts. It is used then in callbacks in order to load html returned from web service). It calls generated web service proxy asynchronously and passes delay, callbacks and containerID (lines 4,5). After that control is returned to the page.

In real life registration of javascript function and asynchronous call to web service is very fast, so web part almost doesn’t affect page loading time. So if you have some slow web part, using of this technique may significantly improve performance and make user experience much better. But let’s continue.

When call reaches web service it makes the following:

   1: [System.Web.Script.Services.ScriptService]
   2: [WebService(Namespace = "http://tempuri.org/", Name = "AsyncWebPartService")]
   3: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
   4: [ToolboxItem(false)]
   5: public class AsyncWebPartService : System.Web.Services.WebService
   6: {
   7:     [ScriptMethod]
   8:     [WebMethod]
   9:     public string GetUIHtmlForAsyncWebPart(int delay)
  10:     {
  11:         var ctrl = new MyControl();
  12:         ctrl.Delay = delay;
  13:  
  14:         var retOutputBuilder = new StringBuilder();
  15:         using (var stringWriter = new StringWriter(retOutputBuilder))
  16:         {
  17:             using (var textWriter = new HtmlTextWriter(stringWriter))
  18:             {
  19:                 ctrl.RenderControl(textWriter);
  20:             }
  21:         }
  22:         return retOutputBuilder.ToString();
  23:     }
  24: }

At first it creates instance of the custom control (line 11). Then it passes custom properties which we got from web part to created control (line 12). In this example we pass delay and control doesn’t make anything except waiting specified amount of seconds. But in real life you may pass all web part custom properties into it. Then service renders control to the string (lines 14-22) and returns the result. Note that as in web method GetUIHtmlForAsyncWebPart we actually create html for our web part, we should create separate web method for each web part which we would like to make asynchronous. Then as I mentioned above generate proxy for it and create javascript function in AsyncWebPart.js. In this example we used custom control, but it is also possible to use user controls with this technique (see e.g. this forum thread: ASP.NET how to Render a control to HTML). After that rendered string is passed back to the client and javascript handler loads it into container inside web part. It happens asynchronously without page re-loading.

The last thing which is worth mentioning is that if you want to use this approach, you need to separate web part from actual logic which renders UI. I.e. web part itself should be just lightweight container. But this is rather a good practice then limitation (e.g. OTB Sharepoint visual web parts are implemented exactly like this: web part is just a container which logic is located inside user control which is loaded dynamically).

That’s all which I would like to write about this approach. Again thanks to Chaitu Madala who shared it with community. Hope this article will help you if you will decide to use Framework for loading SharePoint web parts asynchronously in your work.

Update 2012-11-25: when use this approach you may encounter with the problem of incorrect context site for rendering your web parts. Solution is described here: Problem with context site in Sharepoint when call web service from javascript.