2

Any exprets to work with expressions in C# ?

I fucking don't get it...

var newExpression = oldExpression.Compose(x=> -1 * x) takes fucking 25 milli seconds.

BUT

var newExpression = oldExpression.Compose(x=> x > 0) takes 1 ms (or less).

WTF... the source "oldExpression" is the same in both cases.

First compose used for ordering, second for fdiltering.

1 hour already I'm trying to understand WHY first one is so slow. (It will be called like 500K times a day in prod).

the .Compose is based on :

https://stackoverflow.com/questions...

Comments
  • 1
    Must you do it with an expression?
  • 0
    @spongessuck Well, using expression I'm at about 20-30 lines of code

    I can do a Switch or a bunch of "if.. else".

    But in this case it would be around 500+ lines of code.

    Because there is a method "getExpression" for "Column name" (Columnname mabe a simple fild, but it may also be something like "MyTab;e.Where(confition).Select(Sum or average of something based on column name).

    So using expressions it wraps all of it in a nice code.

    But I did add just extra 8 lines. For ordreing the multiply by -1 is just orderByDescending.

    With expression I don't care if it's order or order desc.

    So I added ifs. I eliminated the slow "-1*Exp" thingy, but kept the fast comparaison thingy.

    So far so good. Fun times :)

    But what was 1 line of code, is now more (cf screenshot)
  • 4
    Don't claim to know what is exactly happening, but to me this seems like an issue with lazy evaluation and caching.

    In any case, 25 ms should not, in most cases, pose a problem.

    I mean, you are likely to hit the same amount of latency just from network anyway.
  • 1
    don't know if this is specifically the case but i remember in cs class we were taught comparing with 0 is always faster. Can't remember why though
  • 0
    @CoreFusionX True

    But you can't know what else server does.

    Maybe 25m shere, than 10, 5, 75 in another places, it adds up !
  • 0
    @iceb in this case I put > 0 as example, it's actually "<. <=. ==. >=. >" all range of values with any value. And with any combination is super fast
  • 4
    @iceb

    Comparison with 0 is fast because it doesn't involve a branch in modern hardware, because superscalar architectures usually have a direct line on the highest sign bit to directly choose the right branch based on the result.

    Caches are a whole different beast which has a lot to do, and many times, counterintuitive.

    For example, in c++, if you want a set, in the conceptual sense (constant time lookup, insert, etc), up to like, 30k entries, a plain vector is more performant just due to cache friendliness.
  • 0
    Not sure if this is also in an expression body but if not you could use a switch expression, something like

    ordered = (isDesc, query) switch
    {
    (true, IOrderedQueryable<TItem>) => query.ThenByDescending(orderExpression),
    (false, IOrderedQueryable<TItem>) => query.ThenBy(orderExpression),
    (false, _) => query.OrderBy(orderExpression),
    _ => query.OrderByDescending(orderExpression)
    };
  • 0
    @spongessuck Ah yeah. Might do that. seems pretty clear
Add Comment