{"action":"created","issue":{"url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/169","labels_url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/169/labels{/name}","comments_url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/169/comments","events_url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/169/events","html_url":"https://github.com/zzzeek/sqlalchemy/pull/169","id":70678924,"number":169,"title":"micro-optimize unique_list","user":{"login":"gdementen","id":832092,"avatar_url":"https://avatars.githubusercontent.com/u/832092?v=3","gravatar_id":"","url":"https://api.github.com/users/gdementen","html_url":"https://github.com/gdementen","followers_url":"https://api.github.com/users/gdementen/followers","following_url":"https://api.github.com/users/gdementen/following{/other_user}","gists_url":"https://api.github.com/users/gdementen/gists{/gist_id}","starred_url":"https://api.github.com/users/gdementen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gdementen/subscriptions","organizations_url":"https://api.github.com/users/gdementen/orgs","repos_url":"https://api.github.com/users/gdementen/repos","events_url":"https://api.github.com/users/gdementen/events{/privacy}","received_events_url":"https://api.github.com/users/gdementen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-04-24T12:34:03Z","updated_at":"2015-04-24T19:51:07Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/zzzeek/sqlalchemy/pulls/169","html_url":"https://github.com/zzzeek/sqlalchemy/pull/169","diff_url":"https://github.com/zzzeek/sqlalchemy/pull/169.diff","patch_url":"https://github.com/zzzeek/sqlalchemy/pull/169.patch"},"body":"This makes unique_list approx 2x faster in my (simple) tests for larg-ish sequences, and a bit faster for smaller ones.\r\n\r\n```python\r\nIn [1]: def unique_list(seq):\r\n   ...:     seen = {}\r\n   ...:     return [x for x in seq\r\n   ...:             if x not in seen\r\n   ...:             and not seen.__setitem__(x, True)]\r\n   ...: \r\n\r\nIn [2]: def unique_list2(seq):\r\n   ...:     seen = set()\r\n   ...:     seen_add = seen.add\r\n   ...:     return [x for x in seq\r\n   ...:             if x not in seen\r\n   ...:             and not seen_add(x)]\r\n   ...: \r\n\r\nIn [3]: l = list(range(10000))\r\n\r\nIn [5]: timeit unique_list(l)\r\n100 loops, best of 3: 2.46 ms per loop\r\n\r\nIn [7]: timeit unique_list2(l)\r\n1000 loops, best of 3: 1.1 ms per loop\r\n\r\nIn [8]: l = list(range(3))\r\n\r\nIn [9]: timeit unique_list(l)\r\n1000000 loops, best of 3: 978 ns per loop\r\n\r\nIn [10]: timeit unique_list2(l)\r\n1000000 loops, best of 3: 702 ns per loop\r\n\r\nIn [14]: l = list(range(int(1e6)))\r\n\r\nIn [15]: timeit unique_list(l)\r\n1 loops, best of 3: 305 ms per loop\r\n\r\nIn [17]: timeit unique_list2(l)\r\n1 loops, best of 3: 159 ms per loop\r\n```"},"comment":{"url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/comments/96045410","html_url":"https://github.com/zzzeek/sqlalchemy/pull/169#issuecomment-96045410","issue_url":"https://api.github.com/repos/zzzeek/sqlalchemy/issues/169","id":96045410,"user":{"login":"zzzeek","id":128223,"avatar_url":"https://avatars.githubusercontent.com/u/128223?v=3","gravatar_id":"","url":"https://api.github.com/users/zzzeek","html_url":"https://github.com/zzzeek","followers_url":"https://api.github.com/users/zzzeek/followers","following_url":"https://api.github.com/users/zzzeek/following{/other_user}","gists_url":"https://api.github.com/users/zzzeek/gists{/gist_id}","starred_url":"https://api.github.com/users/zzzeek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zzzeek/subscriptions","organizations_url":"https://api.github.com/users/zzzeek/orgs","repos_url":"https://api.github.com/users/zzzeek/repos","events_url":"https://api.github.com/users/zzzeek/events{/privacy}","received_events_url":"https://api.github.com/users/zzzeek/received_events","type":"User","site_admin":false},"created_at":"2015-04-24T19:51:07Z","updated_at":"2015-04-24T19:51:07Z","body":"here's 2.7:\r\n\r\n\tunique_list_add_inline, 3, 333333 times: 0.347361803055\r\n\tunique_list_add, 3, 333333 times: 0.348173141479\r\n\tunique_list_setitem_inline, 3, 333333 times: 0.410316944122\r\n\tunique_list_setitem, 3, 333333 times: 0.426838874817\r\n\r\n\r\n\tunique_list_add_inline, 10000, 100 times: 0.159450054169\r\n\tunique_list_add, 10000, 100 times: 0.189424037933\r\n\tunique_list_setitem_inline, 10000, 100 times: 0.227113962173\r\n\tunique_list_setitem, 10000, 100 times: 0.268784999847\r\n\r\n\r\n\tunique_list_add_inline, 1000000, 1 times: 0.204242229462\r\n\tunique_list_add, 1000000, 1 times: 0.241760969162\r\n\tunique_list_setitem_inline, 1000000, 1 times: 0.288633108139\r\n\tunique_list_setitem, 1000000, 1 times: 0.342014074326\r\n"}}