0

Profiling my application I've discovered an unpleasant fact what typed Upadte<> (and Query<>) builder evaluates lambda expressions on each request, consuming a lot of CPU. You will gain several percents of CPU, switching from nice and modern typed UpdateBuilder<> as:

var u = Update<MyPerson>.Inc(e => e.Age, Age);

to old good static strings:

var u = Update.Inc("Age", Age);

The same problem with QueryBuilder<>, it's also evaluates expressions on each request and wastes valuable CPU resources for nothing.

The official LINQ driver's page states:

The C# compiler translates all queries written using query syntax into lambda syntax internally anyway, so there is no performance advantage or penalty to choosing either style.

Yes, it's true if you choose between two LINQ syntaxes. But there is a huge performance difference between using and not using LINQ syntax. Overhead depends on how often your client performing queries. In my case, it's above 30% difference!

Is there any way to get the nice typed syntax and performance both together, I wonder?

Simple caching of builder results is not an answer as far as we obviously need to pass dynamic params to each request. We need to find the way to "pre-compile" CPU-expensive part (concerning lambda expressions evaluation) but preserve dynamic params (ex. array indexes).

Anton Krupnov
  • 51
  • 2
  • 5

1 Answers1

0

The paragraph you quoted:

The C# compiler translates all queries written using query syntax into lambda syntax internally anyway, so there is no performance advantage or penalty to choosing either style.

Refers to the two syntaxes available for writing LINQ queries.

var query =
    from e in collection.AsQueryable<Employee>()
    where e.FirstName == "John"
    select e;

or

var query =
    collection.AsQueryable<Employee>()
    .Where(e => e.FirstName == "John");

It is not meant to imply that LINQ queries in general have no overhead. All LINQ queries must be translated at run time into equivalent MongoDB queries and that process requires a certain amount of CPU time.

We do hope to reduce that overhead if possible in the future, but keep in mind that this overhead occurs only at the client and does not affect the server.

Robert Stam
  • 12,039
  • 2
  • 39
  • 36
  • Yes, that's correct, concerning "two syntaxes available for writing LINQ queries" - there is no any difference. I've updated the question. – Anton Krupnov May 10 '13 at 12:46
  • But this does not answers the main point: why if we have "static" document properties definition, we should suffer from executing quite expensive LINQ queries on each request? If my client mostly works with MongoDb, it consumes 100% CPU on its hardware with only goal to generate more heat to environment. There is no any point to process static metadata on each request. I'd like to use LINQ syntax, I really love it. But unfortunately unable to use it until that issue fixed. – Anton Krupnov May 10 '13 at 12:50
  • And looking forward, there are performance issues in: serializing BSON documents (MongoDB.Bson.IO.MultiChunkBuffer.WriteBackingBytes function) and such often using functions as GetCollection() which is also eats a few percents of CPU and subjected to be pooled in my app. Hope you will profile and tune you driver soon. Thanks in advance. I love you driver and like to hear good news about its performance. – Anton Krupnov May 10 '13 at 13:01