Skip to content

Boolean operations generated IL #635

Description

@thinkbeforecoding

I was doing perf test today and noticed that F# didn't use intrinsic boolean operator with && and ||.
C# also makes some optimizations in release, but the F# version is a bit slower that C#.

The test case uses the following function:

let isAlphaNum (s:string) pos =
    let c = s.[pos]
    (c >= '0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c <= 'z')

when decompiled with dotPeek it looks like:

public static bool isAlphaNum(string s, int pos) {
    char ch = s[pos];
    if ((((int) ch < 48 ? 0 : ((int) ch <= 57 ? 1 : 0)) == 0 ? ((int) ch < 65 ? 0 : ((int) ch <= 90 ? 1 : 0)) : 1) != 0)
      return true;
    if ((int) ch >= 97)
      return (int) ch <= 122;
    return false; }

The following equivalent C# implementation which is highly similar:

        static bool IsAlphaNum(string s, int pos) {
            var c = s[pos];
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';  }

Results in release in:

   private static bool IsAlphaNum(string s, int pos)  {
      char ch = s[pos];
      if ((int) ch >= 48 && (int) ch <= 57 || (int) ch >= 65 && (int) ch <= 90)
        return true;
      if ((int) ch >= 97)
        return (int) ch <= 122;
      return false;    }

If the last lines look the same, F# uses a ternary construct with 1s and 0s instead of using && and || ...

A micro benchmark on 100.000.000 iterations doing the full path (always testing a '}') gives
~417ms for the F# version
~280ms for the C# version

Tests with other charts give an advantage for C#.

The question is: is there a good reason to use ?: == 0 == 1 instead of Boolean && and || native operators ?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions