patterncsharpMinor
Rewriting C# implementation of Snake class in F#
Viewed 0 times
implementationclasssnakerewriting
Problem
This is my C# class, which takes 2.6s:
This is my F# class, which takes 5s:
```
type Snake (mySymbol: Symbol, multiplier, hit, best: Option) =
let payout (mySymbol: Symbol) hit multiplier =
match multiplier wi
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 < bestRecentSnake._payout)
{
this._bestSnake = bestRecentSnake;
}
else if (_payout == bestRecentSnake._payout)
{
if (bestRecentSnake._mySymbol.Type == 1 && 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) =
let payout (mySymbol: Symbol) hit multiplier =
match multiplier wi
Solution
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:
The performance of this should be on par with C#.
( stub )
[]
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 [] Snake private (mySymbol: Symbol, multiplier, hit, bestSnake) as this =
let payout = mySymbol.Payout.[hit - 1] * (match multiplier with 0 -> 1 | m -> m)
let bestSnake =
match bestSnake with
| This -> this
| RecentSnake bestRecentSnake ->
if payout 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 -> null
| resultSymbol -> Snake(resultSymbol, max this.Multiplier nextApple.Multiplier, this.Hit + 1, this.BestSnake)
The performance of this should be on par with C#.
Context
StackExchange Code Review Q#15542, answer score: 5
Revisions (0)
No revisions yet.