How can this be done more elegant and without creating new objects?
List<Move> playerMoves = clone.getValidSuccessorMoves(0);
Lis开发者_开发问答t<Move> opponentMoves = clone.getValidSuccessorMoves(1);
Move pmove = playerMoves[rand.Next(playerMoves.Count)];
Move omove = opponentMoves[rand.Next(opponentMoves.Count)];
MapManipulator.applyMove(clone.Map, pmove);
MapManipulator.applyMove(clone.Map, omove);
clone.Player = pmove.Destination;
clone.Opponent = omove.Destination;
The "select a random item bit" seems to be done:
list[random.Next(list.Count)]
is fine, so long as you're creating instances of Random
appropriately. Given that there's so much code we don't know about though, we can't really answer the other part of your question - you haven't shown anything which actually creates any new objects...
Assuming that your generate moves function is something like:
IEnumerable<Move> getValidSuccessorMoves()
{
if (logic)
yield return new Move(...);
if (otherLogic)
yield return new Move(...);
}
and there is some overhead in generating this (there likely isn't as much as you think there is), you can avoid generating the full list each time by using some logic like follows:
int index = random.Next(MAX_POSSIBLE_MOVES);
List<Move> allMoves = new List<Move>(index);
var moves = getValidSuccessorMoves();
foreach (var move in moves)
{
if (index == 0)
return move;
allMoves.Add(move);
}
index = random.Next(allMoves.Count);
return allMoves[index];
This allows you to short circuit if the RNG picks a good number, and doesn't bias the results. This only really gains you when MAX_POSSIBLE_MOVES is somewhat close to the actual number of moves generated.
However, even with this all said and done, you're likely optimizing too early. Is this really the code that is profiling the worst for you? C# is generally good at lots of short-lived allocations and deallocations (that's what the generational GC is for).
精彩评论