昨日はチューニングっぽいことをした後、眠りにつきました。今日はもう直接仕事をするのではなく、コードのエントロピィを下げる作業をしました。
たとえば、テストコードを見てもらったときに「これは、mock.patch を使いすぎだろwww」と指摘された箇所があります。
class API_UpdateCountsTest(TestBedTestCase):
@patch('poll.api.get')
@patch('backend.api.update_options_in_datastore')
@patch('backend.api.calculate_deltas')
@patch('google.appengine.api.taskqueue.Queue')
def test(self, Queue, calculate, update, get_poll):
...
self.assertEqual(Queue.call_count, 3)
self.assertEqual(Queue.call_args_list[0], ((backend_api.QUEUE_NAMES[0],), {}))
self.assertEqual(queue.lease_tasks.call_count, 2)
self.assertEqual(queue.lease_tasks.call_args, ((backend_api.LEASE_SECONDS, backend_api.MAX_TASKS), {}))
... (以下、大量の assert)
まあ、ひどい。テスト対象の関数の中で、いろんなことをしていて、かつ、それが丸見えになっているのが原因です。手順が多いのは仕方ないのだけれど、データの受け渡しがたくさん丸見えなのがよくない。
def _update_counts(queue_id):
queue_name = QUEUE_NAMES[queue_id]
queue = taskqueue.Queue(queue_name)
tasks = queue.lease_tasks(LEASE_SECONDS, MAX_TASKS)
vote_count = len(tasks)
option_count = 0
if tasks:
payloads = [json.loads(task.payload) for task in tasks]
deltas = calculate_deltas(payloads)
option_count = len(deltas)
update_options_in_datastore(deltas)
# handle done
for data in payloads:
... (まさかの20行くらい)...
# delete task
queue.delete_tasks(tasks)
ひどす。急ぎで性能を上げるために、コードを追加/削除/変更をしたときに、とにかくテストを書いて通すようにした残骸が残っています。こうやってエントロピィが増加するわけです。エントロピィの意味分かってませんが。
というわけで、以下のように変更。
def _update_counts(queue_id):
data = dequeue(queue_id)
if not tasks:
return
update_options(data)
update_dones(data)
それでも patch は 3つくらい必要ですが、assert がシンプルになります。
そんな作業をしていたら、夜が明け、海辺まで散歩し、温泉に浸かり、朝食を食べて、もうすぐ10時になります。解散して、帰宅して寝ます。

