昨日はチューニングっぽいことをした後、眠りにつきました。今日はもう直接仕事をするのではなく、コードのエントロピィを下げる作業をしました。
たとえば、テストコードを見てもらったときに「これは、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時になります。解散して、帰宅して寝ます。