1
hahastudio 2015-06-29 10:06:28 +08:00
这个,基本上,很难
因为一个 iterator 的当前值很有可能是会跟前几次迭代有关的,比如用 generator 写一个 Fibonacci 生成 不知道少开几个线程会怎么样,比如一个线程处理 100W 个这样的 实在不行,用 C/C++ 吧 |
2
neoblackcap 2015-06-29 10:10:39 +08:00
为什么要去遍历一个迭代器?要不说说你具体的需求?你是不是要查找某个元素,还是说必须对每个元素都进行某种操作?
|
3
bigtan 2015-06-29 10:12:40 +08:00 via Android
试试cython,不过还是要看你需要什么操作
|
4
echo1937 2015-06-29 10:22:34 +08:00
用generator去实现,然后多线程去遍历?
|
5
yuankui 2015-06-29 10:28:02 +08:00
知道有GIL这个东西吗?
CPU密集型的job基本多线程与单线程没啥区别... 如果机器cpu没跑满的话,可以试试[多线程](http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431927781401bb47ccf187b24c3b955157bb12c5882d000) 再不行,就分布式吧~ |
6
yuankui 2015-06-29 10:28:38 +08:00
笔误 [多线程]->[多进程]
|
7
aragakiiyui OP @neoblackcap @bigtan 其实我程序的功能就是把es中某个表的所有元素取出来,然后对每个元素进行一些处理,最后放到一个新的表中。 拿的这个过程请忽略,反正就是拿出了一个包含800多万数据的迭代器。我想知道有没有什么方法,可以将这个迭代器拆成多个部分去多线程处理?如果直接跑一个for循环的话需要将近两个小时,完全没法完成需求。。。
|
8
mhycy 2015-06-29 10:31:22 +08:00
单线程遍历并异步分发,多线程处理。。。
|
9
aragakiiyui OP @hahastudio 我测了一下,发现使用islice拆分的话,islice操作占到总时间的40%以上。线程开多了反而更慢。
|
10
aragakiiyui OP @mhycy 嗯,我现在打算这么试试看,能改进一些么。
|
11
mhycy 2015-06-29 10:36:16 +08:00
@aragakiiyui
你没说清楚你的那个处理是做啥的能改善多少没法说清。。。 如果是CPU压力大的应用,写个C/C++扩展吧,多进程是必须的了。 如果是IO压力大的应用,改善IO才是最重要的。 关键是我们不知道你做的是啥操作。。。 说回来800W数据都在内存? |
12
0bit 2015-06-29 10:37:35 +08:00
为啥不在取的时候处理呢,分发给多进程,用offset来取数据
|
13
seki 2015-06-29 10:59:19 +08:00
multiprocessing map 不知道管不管用
|
14
aragakiiyui OP @mhycy 那我详细说一下吧,我要做的工作是把es中的3个表并作一个表。我要遍历其中三个表中主要的那个表然后结合另外两个表中对应的数据,把数据一条一条拼起来。最后将拼好的数据写到一个新的表中。写操作大概每次1000条效率最高。
使用es的接口取出的那个表是个迭代器,所以800w数据不直接放内存里的。 |
15
neoblackcap 2015-06-29 11:13:48 +08:00 1
@aragakiiyui 既然是从es里面拿的,为什么还有自己切分数据?根据条件筛选出来不就好了,然后就可以直接分布式。
比如client从redis或者rabbitmq里面提取要处理的数据主键范围(eg. 1-1000 或者2000-3000)然后根据这个条件从es里面筛选出结果,然后就自行进行处理,然后写入数据库。这样你看行不? |
16
mhycy 2015-06-29 11:18:34 +08:00 1
|
17
arbipher 2015-06-29 11:43:12 +08:00
原始数据是迭代器,"转换成list"的话,不是凭空多了很多内存复制?
|
18
mozartgho 2015-06-29 11:44:37 +08:00
写C/C++扩展吧,一般这种效率至上的考虑用C/C++
|
19
aragakiiyui OP @neoblackcap 我来试试看。
|
20
aragakiiyui OP @neoblackcap 我试过了,直接条件筛选后,整体更加慢了,这样还不如直接全部取出来切分,而且我试了一个队列从迭代器中读取数据,另外开五个线程执行写的任务,虽然快了一点,但是效率提升仍然不明显。。。
|
21
nullcc 2015-06-29 16:00:48 +08:00
考虑下map reduce?
|
22
aragakiiyui OP @nullcc 用多进程么?!
|
23
neoblackcap 2015-06-29 16:12:53 +08:00
@aragakiiyui 你这个工作差不多都已经完全是分布式了,你至少是用多进程啊。队列只是拿worker要完成那种任务的条件而已,
就好像你告诉worker要去处理1-1000的记录,worker2处理2000-3000的记录,但是具体的信息还是要通过es去读(每个worker独自建个连接连es来获取信息)。若是你的数据没有依赖关系的话,即worker1处理完的内容可以直接写入数据库,那么你就完全连合并的server端都省了,worker直接写数据库就可以了。这样下来效率应该很高才对啊。处理完全是分布式啊,最大的瓶颈就是磁盘IO而已。即es的读或者数据的写 |
24
clino 2015-06-29 16:19:07 +08:00
"我要处理的一个Iterators大概包含了将近900万个元素"
把元素分段,然后这样可以用多个 iterator 来不重复地遍历,这样就可以多线程或者多进程地并行了 |
25
nullcc 2015-06-29 16:32:35 +08:00
@aragakiiyui 怎么说呢。。map reduce是一种编程模型,有分布式的概念了
|
26
julyclyde 2015-07-01 18:06:19 +08:00
先把迭代器list化,然后再用slice的话小心内存占用量哦
|
27
aragakiiyui OP @neoblackcap @clino 我多进程也试了,我把那块大的数据分成了2块,然后跑两个进程,发现比单进程慢的多。然后我又试了分成四块,跑四个线程,依然不如单线程跑。。我的机器实在太渣了。。瓶颈确实在IO上面。
|