Tag Archives: performance

Best Browser for Low Resource Computer

My wife and I keep a netbook in our living room for lightweight, everyday computing. It is used almost exclusively for checking email and general internet browsing. The specs on the netbook, like most netbooks, are not terribly impressive: 1.66 GHz CPU, 1 GB RAM. It’s been a good, little computer, but recently the performance has become a problem.

My wife and I both use Chrome as our primary browser. When I pick up the computer, and there are a bunch of tabs left open by my wife, I leave them open under the assumption that they were left open intentionally, and my wife gives me the same courtesy. I know that Chrome runs each tab as a separate process, and I suspected that the large number of tabs that were frequently open might have been causing our performance woes. I decided to do some resource testing with each of browsers installed on the netbook: Internet Explorer 9, Chrome, Firefox, and Safari.

For my test, I opened each browser with three tabs and browsed to my Gmail inbox with each. I wanted to see how many processes were created by doing this and how much total memory was used by each browser in doing so.

  • Chrome: 5 processes (for 3 tabs), ~40K memory each
  • Internet Explorer: 3 processes, ~30K memory each
  • Firefox: 1 process, ~115K memory
  • Safari: 2 processes (for 3 tabs), ~20K memory
    • …but also WebKit2WebProcess.exe: 1 process, ~120K memory

So, my hypothesis is that Chrome is actually the worst browser to use on a low resource machine since it spawns the most processes and uses the most memory per process. Internet Explorer and Firefox seem like they may be a push. My guess is that Firefox will outperform IE on a low-end machine since there is only a single process, but I have not tested this or even spent much time thinking about it. Safari seems like the wild card in the equation. It uses the least amount of memory per process, but it relies on the separate WebKit2WebProcess process which seemingly offsets the per-process memory savings.

This article seems to support my claim, stating that Firefox is the best choice for users with less than 2 GB of RAM. That article linked to another article on the same site about reducing Chrome’s memory usage, which would obviously improve Chrome’s performance on low-end hardware.

Advertisements

TFS SDK: Improve Performance of Parent-Child Queries

I’ve been helping a co-worker with a web application that we’ll be using in lieu of generating daily stand-up reports from Excel spreadsheets connected to TFS. We want this application to retrieve a list of User Stories and their child Tasks by Iteration Path and display them per user.

One of the pain points of Excel is that refreshing our TFS queries is a slow process that keeps getting slower as more data is added. So a key requirement of this project is to have fast-running queries. We’re writing queries using WIQL, which I’ve touched on previously. WIQL has okay performance, but executing queries is an expensive operation. You can improve the performance of your application by executing larger queries and then filtering programmatically instead of doing many queries for specific information.

For this example, I have a query to retrieve all User Stories. I’m using Iteration Path to filter items to just my team.

SELECT *
FROM WorkItems 
WHERE [System.WorkItemType] = 'User Story'
    AND [System.IterationPath] UNDER 'MyTeam\'

Each of the returned User Story work items has a collection of links. If we want to retrieve all the child work items, we can look at the link type and retrieve items by Id. The most obvious solution is to loop through collection of linked work items and retrieve any children. This code does just that:

var linkType = workItemStore.WorkItemLinkTypes
    .LinkTypeEnds["System.LinkTypes.Hierarchy-Forward"];

foreach (WorkItem d in deliverables)
{
    var stories = d.WorkItemLinks.OfType<WorkItemLink>()
        .Where(x => x.LinkTypeEnd == linkType)
        .Select(x => 
            workItemStore.Query(@"
                SELECT *
                FROM WorkItems 
                WHERE [System.Id] == " + x.TargetId)
            .Cast<WorkItem>().FirstOrDefault());
}

This solution works, but it’s slow due to the number of queries being executed. We can get a great performance boost by simply retrieving the collection of Tasks and querying the in-memory collection to find each Story’s children, like this:

var userStories = workItemStore.Query(@"
    SELECT *
    FROM WorkItems 
    WHERE [System.WorkItemType] = 'Task'
        AND [System.IterationPath] UNDER 'MyTeam\'
    ").Cast<WorkItem>();

var linkType = workItemStore.WorkItemLinkTypes
    .LinkTypeEnds["System.LinkTypes.Hierarchy-Forward"];

foreach (WorkItem d in deliverables)
{
    var stories = d.WorkItemLinks.OfType<WorkItemLink>()
        .Where(x => x.LinkTypeEnd == linkType)
        .Select(x => 
            userStories.Where(us => us.Id == x.TargetId)
                .FirstOrDefault());
}

I wrote a quick test program to test the performance gained by using this technique, and the results were quite dramatic. (55.3%!)

Average time to retrieve 85 User Stories with 250 linked child Tasks:
Method A (querying per link): avg. 4817.67 ms
Method B (query for all tasks up-front): avg. 2151.33 ms

The lesson to be learned here is that it’s typically best to execute broader queries and filter programmatically rather than to execute many queries for specific information. The above example could be improved further by retrieving Tasks and User Stories in a single query. The application could then extract User Stories from the results collection and retrieve linked Tasks from the same collection by Id.