2013-11-25 77 views
0

我有一个代码,它放置其数据并将其声明在字典中。 我目前在我的for循环中有很长的时间,大约200,000个数据需要大约2个小时。 现在我在想如果我有200万的数据还有什么。优化Python中的for循环

这里是我的for循环示例(对不起,变量的命名,这只是我的示例代码):

# Gets the data in database 
data_list = self.my_service.get_database_list() 

my_dict_list = {} 

for item in data_list: 
    primary_key = item.primarykey 
    value = item.name + item.address + item.age 

    my_dict_list[primary_key] = value 

这是我的模型/数据库获取代码:

def get_database_list(self): 
    return self.session.query(
     self.mapper.name, 
     self.mapper.addreess, 
     self.mapper.age, 
     ) 

我的数据库引擎是InnoDB。 有没有办法让它稍微优化或循环数据更快。 感谢您的分享。

+3

我猜了'my_service.get_database_list()'不返回一个迭代器? –

+0

@limelights,嗨,你是什么意思的迭代器? – Bazinga

+2

我认为他的意思是一个生成器 - 一个对象,可以迭代每个项目的项目,而不必先建立一个巨大的内存列表。那是你最可能的罪魁祸首; 'for'循环看起来像你可以做到的那样紧凑。 –

回答

3

首先,我怀疑你的瓶颈(几个小时)在python部分。你可以通过生成器和字典理解来获得一些改进,但是通过多少?寻找200个000行的样本:

import base64 
import os 
def random_ascii_string(srt_len): 
    return base64.urlsafe_b64encode(os.urandom(3*srt_len))[0:srt_len] 

>>> data = [{'id': x, 'name': random_ascii_string(10), 'age':'%s' % x, 
      'address': random_ascii_string(20)} for x in xrange(2*10**5)] 

你的方法

>>> timeit.timeit(""" 
... from __main__ import data 
... my_dict_list = {} 
... for item in data: 
...  my_dict_list[item['id']] = item['name'] + item['address'] + item['age']""", 
...   number = 100) 
16.727806467023015 

列表理解

>>> timeit.timeit("from __main__ import data; " 
... "my_dict_list = { d['id']: d['name']+d['address']+d['age'] for d in data}", 
...  number = 100) 
14.474646358685249 

我怀疑你能找到这些优化两小时。所以你的第一个任务是找到你的瓶颈。我劝你看看你工作的MySQL的部分,大概它redisign到:

  • 使用每桌单独INNO DB文件,如果检索数据
  • 使一些较小的一部分
  • 使用索引评估在DB的一面,比如name + address + age
  • 不作处理整个数据,仅检索需要的部分(第几行)
0

同意以上对迭代器的评论。你可以尝试用字典理解来代替循环。

import uuid 
import time 

class mock: 
    def __init__(self): 
     self.name = "foo" 
     self.address = "address" 
     self.age = "age" 
     self.primarykey = uuid.uuid4() 

data_list = [mock() for x in range(2000000)] 

my_dict_list = {} 
t1 = time.time() 
for item in data_list: 
    primary_key = item.primarykey 
    value = item.name + item.address + item.age 
    my_dict_list[primary_key] = value 
print(time.time() - t1) 


my_dict_list = {} 
t2 = time.time() 
new_dict = { item.primarykey: item.name + item.address + item.age for item in data_list } 
print(time.time() - t2) 
2

很难猜测代码花在哪里的最多时间。最好的办法是使用cProfile来运行它,并检查结果。

python -m cProfile -o prof <your_script> <args...> 

它输出一个名为prof文件,您可以通过多种方式检查,最酷的,其中使用runsnakerun

除此之外,关闭头顶,字典,comrehension往往快于备选方案:(?是他们所有的字符串)

my_dict_list = { item.primarykey: item.name + item.address + item.age } 

此外,它是不完全清楚什么item.name + item.address + item.age确实,但如果您可以考虑更改数据结构,并存储item而不是该组合值,则可能会有所帮助。

+0

是的,他们都是字符串。 – Bazinga