Izzy
Izzy

Reputation: 6866

Trying to optimize linq query

I am trying to create a linq query to do the following:

  1. Get count of all users
  2. Get count of all official users
  3. Get count of all non-official users

So far I have come up with the below:

var query = context.Users;

List<Users> users = query.ToList();
int totalUsers = users.Count;
int officialUsers = users.Where(s => s.IsOfficialUser).ToList().Count;
int nonOfficialUsers = users.Where(s => !s.IsOfficialUser).ToList().Count;

I'm not sure how much performance impact will happen by me calling .ToList() numerous times. So I was hoping is there a way to optimize the query or am I on the right track?

Upvotes: 4

Views: 89

Answers (3)

Jeremy Thompson
Jeremy Thompson

Reputation: 65534

One easy optimisation:

int totalUsers = users.Count;
int officialUsers = users.Where(s => s.IsOfficialUser).ToList().Count;
int nonOfficialUsers = totalUsers - officialUsers;

Once this line of code is run List<Users> users = query.ToList(); the query is immediately executed.

You don't need the ToList() again after that, see here:

int totalUsers = users.Count;
int officialUsers = users.Count(s => s.IsOfficialUser);
int nonOfficialUsers = totalUsers - officialUsers;

Upvotes: 3

sujith karivelil
sujith karivelil

Reputation: 29006

What about this method?

  • Group your collection based on IsOfficialUser which gives you two collections of nonOfficialUsers and officialUsers right?
  • Get the count of those collections separately to get the respective counts
  • Sum of these counts will be the total right?

Now try this Example:

 var groupedUsers = users.GroupBy(x => x.IsOfficialUser).ToDictionary(g =>  g.Key, g=>g.Count());
 int officialUsers = groupedUsers[true];
 int nonOfficialUsers = groupedUsers[false];
 int totalUsers = nonOfficialUsers + officialUsers;

Upvotes: 0

Travis J
Travis J

Reputation: 82267

Using .ToList on a materialized list will only impact the amount of memory required. While this can technically have a performance hit, it is unlikely unless you have millions of users; in which case, you would honestly probably have the server RAM available anyway.

The .ToList certainly isn't required though. All you are needing to do is count the differentiation here, so you can skip the ToList, and the Where (as Count accepts a Func)

int officialUsers = users.Count(s => s.IsOfficialUser);
int nonOfficialUsers = users.Count(s => !s.IsOfficialUser);

Upvotes: 3

Related Questions