Microptimize MoveList loop
authorMarco Costalba <mcostalba@gmail.com>
Sun, 19 May 2013 20:00:49 +0000 (22:00 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 19 May 2013 20:00:49 +0000 (22:00 +0200)
Add MOVE_NONE at the tail, this allows to loop
across MoveList checking for *it != MOVE_NONE,
and because *it is used imediately after compiler
is able to reuse it.

With this small patch perft speed increased of 3%

And it is also a semplification !

No functional change.

src/book.cpp
src/movegen.h
src/notation.cpp
src/position.cpp
src/search.cpp
src/thread.cpp

index b906d766779ae8fbd391ef2d99b066dd44428ee4..caf2b0663ec76987720231e29360c6d434238d27 100644 (file)
@@ -436,7 +436,7 @@ Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest
       move = make<PROMOTION>(from_sq(move), to_sq(move), PieceType(pt + 1));
 
   // Add 'special move' flags and verify it is legal
-  for (MoveList<LEGAL> it(pos); !it.end(); ++it)
+  for (MoveList<LEGAL> it(pos); *it; ++it)
       if (move == (*it ^ type_of(*it)))
           return *it;
 
index 9db23dd407c1d23e35d03cb4874040005c3b931b..f8c4f22c8b43ae1cde8f013c9dac2c85c0366e2d 100644 (file)
@@ -41,10 +41,9 @@ MoveStack* generate(const Position& pos, MoveStack* mlist);
 template<GenType T>
 struct MoveList {
 
-  explicit MoveList(const Position& pos) : cur(mlist), last(generate<T>(pos, mlist)) {}
+  explicit MoveList(const Position& pos) : cur(mlist), last(generate<T>(pos, mlist)) { last->move = MOVE_NONE; }
   void operator++() { cur++; }
   Move operator*() const { return cur->move; }
-  bool end() const { return cur == last; }
   size_t size() const { return last - mlist; }
   bool contains(Move m) const {
     for (const MoveStack* it(mlist); it != last; ++it) if (it->move == m) return true;
index 0a97d9fd2ba04706e9e686a4fba7788762cd2e5e..c96b9dbe78c1fb93fe69d67639ce4efb11f366bc 100644 (file)
@@ -89,7 +89,7 @@ Move move_from_uci(const Position& pos, string& str) {
   if (str.length() == 5) // Junior could send promotion piece in uppercase
       str[4] = char(tolower(str[4]));
 
-  for (MoveList<LEGAL> it(pos); !it.end(); ++it)
+  for (MoveList<LEGAL> it(pos); *it; ++it)
       if (str == move_to_uci(*it, pos.is_chess960()))
           return *it;
 
index 80130fec97e961bdd201a94e81cca8045c8a95a5..1a8c7e00d6a0bc24af2e44c395a70fb9eb6c1d4b 100644 (file)
@@ -408,7 +408,7 @@ const string Position::pretty(Move move) const {
       ss << square_to_string(pop_lsb(&b)) << " ";
 
   ss << "\nLegal moves: ";
-  for (MoveList<LEGAL> it(*this); !it.end(); ++it)
+  for (MoveList<LEGAL> it(*this); *it; ++it)
       ss << move_to_san(*const_cast<Position*>(this), *it) << " ";
 
   return ss.str();
index a932cf32e37a7e54d4bb4fdd5fc8b9f61c1ceb26..8ba5b41af8be9cf182a02650dc9457d7fa515239 100644 (file)
@@ -163,7 +163,7 @@ size_t Search::perft(Position& pos, Depth depth) {
   size_t cnt = 0;
   CheckInfo ci(pos);
 
-  for (MoveList<LEGAL> it(pos); !it.end(); ++it)
+  for (MoveList<LEGAL> it(pos); *it; ++it)
   {
       pos.do_move(*it, st, ci, pos.move_gives_check(*it, ci));
       cnt += perft(pos, depth - ONE_PLY);
index 71b9ce0c091412e6424791c1e38bd4553fc04f7c..782cf1acc0dd5153fb8ba3bebad8cf69bc35da12 100644 (file)
@@ -371,7 +371,7 @@ void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
   SetupStates = states; // Ownership transfer here
   RootMoves.clear();
 
-  for (MoveList<LEGAL> it(pos); !it.end(); ++it)
+  for (MoveList<LEGAL> it(pos); *it; ++it)
       if (   searchMoves.empty()
           || std::count(searchMoves.begin(), searchMoves.end(), *it))
           RootMoves.push_back(RootMove(*it));