首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C#重写Snake类的F#实现

用C#重写Snake类的F#实现
EN

Code Review用户
提问于 2012-09-12 15:39:15
回答 1查看 777关注 0票数 5

这是我的C#类,它需要2.6s:

代码语言:javascript
复制
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;
    }

这是我的F#类,它需要5s:

代码语言:javascript
复制
type Snake (mySymbol: Symbol, multiplier, hit, best: Option<Snake>) =

let payout (mySymbol: Symbol) hit multiplier = 
    match multiplier with
    | 0 -> mySymbol.Payout_.[hit-1]
    | a -> 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 < a.Payout -> a
    | Some a when this.Payout = a.Payout && a.MySymbol.Type = 1 && mySymbol.Type <> 1 -> a
    | _ -> 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 -> Operators.Unchecked.defaultof<Snake>
    | Some a -> Snake (a, (max multiplier myApple.Multiplier), hit+1, Some this.BestSnake)
EN

回答 1

Code Review用户

回答已采纳

发布于 2012-09-12 18:51:18

你的翻译有几个小差异。我会从直译开始,然后优化/使习语从那里开始。如果以增量的方式完成,那么在出现性能问题时应该很容易发现。这里有一个起点:

代码语言:javascript
复制
(* stub *)
[<AllowNullLiteral>]
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 [<AllowNullLiteral>] 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 < bestRecentSnake.Payout || 
        (payout = bestRecentSnake.Payout && bestRecentSnake.MySymbol.Type = 1 && mySymbol.Type <> 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)

这方面的性能应该与C#相当。

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/15542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档