Rewriting C# implementation of Snake class in F# This is my C# class, which takes 2.6s:

class Snake
{
    readonly Symbol _mySymbol;
    readonly int _multiplier;
    readonly int _hit;
    readonly int _payout;
    readonly Snake _bestSnake;

    public Symbol MySymbol { get { return _mySymbol; } }
    public int Multiplier { get { return _multiplier; } }
    public int Hit { get { return _hit; } }
    public int Payout { get { return _payout; } }

    public Snake BestSnake { get { return _bestSnake; } }

    public Snake(Apple myApple)
    {
        this._mySymbol = myApple.MySymbol;
        this._multiplier = myApple.Multiplier;
        this._hit = 1;
        this._payout = _mySymbol.Payout_[0] * (_multiplier == 0 ? 1 : _multiplier);
        this._bestSnake = this;
    }

    Snake(Symbol mySymbol, int multiplier, int hit)
    {
        this._mySymbol = mySymbol;
        this._multiplier = multiplier;
        this._hit = hit;
        this._payout = _mySymbol.Payout_[hit - 1] * (multiplier == 0 ? 1 : multiplier);
        this._bestSnake = this;
    }

    Snake(Symbol mySymbol, int multiplier, int hit, Snake bestRecentSnake)
        : this(mySymbol, multiplier, hit)
    {
        if (_payout &lt; bestRecentSnake._payout)
        {
            this._bestSnake = bestRecentSnake;
        }
        else if (_payout == bestRecentSnake._payout)
        {
            if (bestRecentSnake._mySymbol.Type == 1 &amp;&amp; mySymbol.Type != 1)
            {
                this._bestSnake = bestRecentSnake;
            }
        }
    }

    public Snake Eat(Apple nextApple)
    {
        var resultSymbol = Symbol.Add(_mySymbol, nextApple.MySymbol);
        if (resultSymbol == null)
            return null;

        var newSnake = new Snake(resultSymbol, Math.Max(_multiplier, nextApple.Multiplier), Hit + 1, _bestSnake);

        return newSnake;
    }


This is my F# class, which takes 5s:

type Snake (mySymbol: Symbol, multiplier, hit, best: Option&lt;Snake&gt;) =

let payout (mySymbol: Symbol) hit multiplier = 
    match multiplier with
    | 0 -&gt; mySymbol.Payout_.[hit-1]
    | a -&gt; mySymbol.Payout_.[hit-1] * a

new (myApple: Apple) = Snake (myApple.MySymbol, myApple.Multiplier, 1, None)

member this.BestSnake =
    match best with
    | Some a when this.Payout &lt; a.Payout -&gt; a
    | Some a when this.Payout = a.Payout &amp;&amp; a.MySymbol.Type = 1 &amp;&amp; mySymbol.Type &lt;&gt; 1 -&gt; a
    | _ -&gt; this

member this.MySymbol = mySymbol
member this.Payout = payout mySymbol hit multiplier
member this.Multiplier = multiplier
member this.Hit = hit

member this.Eat (myApple: Apple) =
    let tmp = Symbol.Add mySymbol myApple.MySymbol
    match tmp with
    | None -&gt; Operators.Unchecked.defaultof&lt;Snake&gt;
    | Some a -&gt; Snake (a, (max multiplier myApple.Multiplier), hit+1, Some this.BestSnake)
There are a few small differences in your translation. I would start with as literal a translation possible, then optimize/make idiomatic from there. If done incrementally it should be easy to spot performance problems as they occur. Here's a starting point:

(* stub *)
[&lt;AllowNullLiteral&gt;]
type Symbol =
  member x.Payout = [|0|]
  member x.Type = 0
  static member Add(sym1, sym2) : Symbol = null

(* stub *)
type Apple =
  abstract MySymbol : Symbol
  abstract Multiplier : int

type private BestSnake =
  | This
  | RecentSnake of Snake

and [&lt;AllowNullLiteral&gt;] Snake private (mySymbol: Symbol, multiplier, hit, bestSnake) as this =
  let payout = mySymbol.Payout.[hit - 1] * (match multiplier with 0 -&gt; 1 | m -&gt; m)
  let bestSnake =
    match bestSnake with
    | This -&gt; this
    | RecentSnake bestRecentSnake -&gt;
      if payout &lt; bestRecentSnake.Payout || 
        (payout = bestRecentSnake.Payout &amp;&amp; bestRecentSnake.MySymbol.Type = 1 &amp;&amp; mySymbol.Type &lt;&gt; 1) 
      then bestRecentSnake
      else null

  member val MySymbol : Symbol = mySymbol
  member val Multiplier = multiplier
  member val Hit = hit
  member val BestSnake = bestSnake
  member val Payout = payout

  new (mySymbol, multiplier, hit, bestRecentSnake) = Snake(mySymbol, multiplier, hit, RecentSnake bestRecentSnake)
  new (mySymbol, multiplier, hit) = Snake(mySymbol, multiplier, hit, This)
  new (myApple: Apple) = Snake(myApple.MySymbol, myApple.Multiplier, 1, This)

  member this.Eat(nextApple: Apple) =
    match Symbol.Add(this.MySymbol, nextApple.MySymbol) with
    | null -&gt; null
    | resultSymbol -&gt; Snake(resultSymbol, max this.Multiplier nextApple.Multiplier, this.Hit + 1, this.BestSnake)


The performance of this should be on par with C#.