maxpumperla / deep_learning_and_the_game_of_go

Code and other material for the book "Deep Learning and the Game of Go"
https://www.manning.com/books/deep-learning-and-the-game-of-go
989 stars 390 forks source link

Why is the "fast_go_strings" class fast? #112

Closed ziyuezzy closed 8 months ago

ziyuezzy commented 8 months ago

Hi, I am probably asking a stupid question, but why is the "fast_go_strings" class faster than the basic "go_string" class?

I noticed that the "fast_go_strings" class basically define most data structures 'readonly' (e.g., 'frozenset'), and the motheds all adapt to that. But won't this lead to more frequent class object initialization and more copies of data?

I didn't find an answer in the book, nor in the comments in the code. Maybe anyone has more insight on this could help me out? Thanks!

macfergus commented 8 months ago

Hi @ziyuezzy, this is a great question. This is something we just didn't have room to cover in the book

The speedup comes when you create a new GameState. GameState is immutable (to help with building search trees), so apply_move creates a new GameState. When you call apply_move, it does a deepcopy on the board: https://github.com/maxpumperla/deep_learning_and_the_game_of_go/blob/master/code/dlgo/goboard_slow.py#L179

When you deepcopy the board, it does a deepcopy of every GoString object. However, when you place a stone, most stones on the board are unaffected. Only strings adjacent to the point you play on may change. So I realized we could eliminate most of those copies.

In the faster implementation, we override the __deepcopy__ method on GoString so it does not copy its point set: https://github.com/maxpumperla/deep_learning_and_the_game_of_go/blob/master/code/dlgo/goboard_fast.py#L90

So the point of switching to frozenset is so two GoString instances can share their stones set safely, thereby allowing us to eliminate copying most of the stone sets.

This turns out to be a measurable speedup, but not massive. I recall it was something like 20% faster (but it was a while ago, so I may be wrong)

BTW -- there is a much faster version of go logic library here: https://github.com/macfergus/baduk/tree/master

It's a Cython extension and I think it's around 10x faster. Unfortunately, it's not quite a drop-in replacement, but the interface is pretty similar to what's in the book

ziyuezzy commented 8 months ago

Thanks!