"""
在处理撮合的逻辑中,有这样一个问题:
以买入委托队列为例:需要维护一个价格由高到低的价格顺序。
对这个价格顺序下有以下两种方案:
1. 使用list
2. 使用deque
"""
import random
import timeit
from collections import deque
def random_int_list(start, stop, length):
start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
length = int(abs(length)) if length else 0
random_list = []
for i in range(length):
random_list.append(random.randint(start, stop))
return random_list
def test_list(_p_list):
"""
List方案, 完全使用list,不借助其它手段
"""
p_list = []
for p_in in _p_list:
if p_in not in p_list:
idx = 0
for p in p_list:
if p_in > p:
break
idx += 1
p_list.insert(idx, p_in)
pass
return p_list
def test_list_withset(_p_list):
"""
List方案,借助一个set,来加速 if not in判断
"""
p_list = []
p_set = set()
for p_in in _p_list:
if p_in not in p_set:
idx = 0
for p in p_list:
if p_in > p:
break
idx += 1
p_list.insert(idx, p_in)
p_set.add(p_in)
pass
return p_list
def test_list_withset_next(_p_list):
"""
List方案,借助一个set,来加速if not in判断;使用next函数来查找第一个符合条件的元素
参考http://stackoverflow.com/questions/2361426/what-is-the-best-way-to-get-the-first-item-from-an-iterable-matching-a-condition
中提到的first_index = next(index for index, value in enumerate(the_iterable) if condition(value))
"""
p_list = []
p_set = set()
for p_in in _p_list:
if p_in not in p_set:
first_index = next((index for index, value in enumerate(p_list) if p_in > value), len(p_list))
p_list.insert(first_index, p_in)
p_set.add(p_in)
pass
return p_list
def test_list_withset_sort(_p_list):
"""
List方案
不自己维护排序,借助一个set,来加速if not in判断; 每次插入都排序
"""
p_list = []
p_set = set()
for p_in in _p_list:
if p_in not in p_set:
p_list.append(p_in)
p_list.sort(reverse=True)
p_set.add(p_in)
pass
return p_list
def test_queue(_p_list):
"""
deque方案
"""
p_queue = deque()
for p_in in _p_list:
if p_in not in p_queue:
idx = 0
for p in p_queue:
if p_in > p:
break
idx += 1
p_queue.insert(idx, p_in)
pass
return p_queue
def test_queue_withset(_p_list):
"""
deque方案
"""
p_queue = deque()
p_set = set()
for p_in in _p_list:
if p_in not in p_set:
idx = 0
for p in p_queue:
if p_in > p:
break
idx += 1
p_queue.insert(idx, p_in)
p_set.add(p_in)
pass
return p_queue
if __name__=='__main__':
# 模拟价格区间在9~11元的随机值
random_price_list = random_int_list(90000, 110000, 10000)
p_list = test_list(random_price_list)
p_list2 = test_list(random_price_list)
p_queue = test_queue(random_price_list)
print(p_list[0], p_list[-1], p_list2[0], p_list2[-1], p_queue[0], p_queue[-1])
print(timeit.timeit('test_list(random_price_list)', number=10, globals=globals()))
print(timeit.timeit('test_list_withset(random_price_list)', number=10, globals=globals()))
print(timeit.timeit('test_list_withset_next(random_price_list)', number=10, globals=globals()))
print(timeit.timeit('test_list_withset_sort(random_price_list)', number=10, globals=globals()))
print(timeit.timeit('test_queue(random_price_list)', number=10, globals=globals()))
print(timeit.timeit('test_queue_withset(random_price_list)', number=10, globals=globals()))
以下是输出结果:
109999 90000 109999 90000 109999 90000
22.2045529369317
16.38033776747557
15.252241216916637
8.420866390707168
26.823208546270322
18.25433301937217
可以看出使用test_list_withset_sort是最快的!
也请大家帮忙看看是否还有更好的方案,谢谢!