2015-04-04 2 views
0

Я пытаюсь оптимизировать свой код для работы в кластере hadoop. Может ли кто-нибудь помочь мне найти способы сделать это лучше? Я беру в очень большом наборе номеров более 40 миллионов, и каждый номер находится на новой линии. Когда числа читаются, я подсчитываю каждое число, суммируя все числа, а также проверяя каждое число, чтобы увидеть, является ли оно простым.Функция карты, которая должна быть быстрее

#!/usr/bin/env python 

import sys 
import string 
import math 

total_of_primes = 0 
total = 0 
count = 0 
not_prime = 0 
count_string = 'Count:' 
total_string = 'Total:' 
prime_string = 'Number of Primes:' 

for line in sys.stdin: 
    try: 
    key = int(line) 
    except: 
    continue 
    total = total + key 
    count = count + 1 
    if key == 2 or key == 3: 
    not_prime = not_prime - 1 
    elif key%2 == 0 or key%3 == 0: 
    not_prime = not_prime + 1 
    else: 
    for i in range(5,(int(math.sqrt(key))+1),6): 
     if key%i == 0 or key%(i+2) ==0: 
     not_prime = not_prime + 1 
     break 

total_of_primes = count - not_prime 


print '%s\t%s' % (count_string,count) 
print '%s\t%s' % (total_string,total) 
print '%s\t%s' % (prime_string,total_of_primes) 
+1

Почему бы вы * уменьшить * количество составных чисел, когда вы видите 2 или 3? – user2357112

+0

2 и 3 - оба простых числа, однако 1 не является. –

+0

Да, но если входные данные - это только два числа 2 и 3, вы видели отрицательные два составных числа? – user2357112

ответ

0

Я попытался взять все и превратить в понимание. Понимание быстрее, чем собственный код Python, потому что они обращаются к библиотекам C. Я также пропустил тест для 2 и 3, так как вы можете просто добавить их вручную, как только закончите цикл.

Я могу в значительной степени гарантировать, что у этого будут ошибки, потому что у меня нет тестовых данных и понимания этого большого (для меня, во всяком случае) действительно нужно тестирование. Это технически однострочный, но я попытался разделить его на читаемость. Надеюсь, хотя это, по крайней мере, дает вам некоторые идеи.

biglist = [ # this will be a list of booleans 
    not int(line)%2 or # the number is not even 
    not int(line)%3 or # not divisible by 3 
    (
     not int(line)%i or # not divisible by each item in the range() object 
     not int(line)%(i+2) for i in # nor by 2 greater than each item 
      # and only go through the range() object while it's still prime 
      itertools.takewhile(lambda x: not int(line)%x or not int(line)%(x+2), 
     range(5, int(pow(int(line), 0.5))+1, 6)) # pow(x, 0.5) uses a built-in instead of an imported module 
    ) 
for line in sys.stdin) if line.lstrip('-+').isdigit() # going through each item in sys.stdin 
# as long as long as it's a digit. if you only expect positive numbers, you can omit ".lstrip('-+')". 
] 

total_of_primes = len(biglist) + 2 # manually add 2 and 3 instead of testing it 

Если вы не можете получить время выполнения вниз достаточно далеко, вы могли бы рассмотреть вопрос о переходе на более низком уровне (медленнее писать, быстрее бежать) язык, как C.

+0

«Понимание быстрее, чем собственный код Python, потому что они обращаются к библиотекам C» - они не делают этого в большей степени, чем эквивалентный цикл. Я считаю, что есть некоторые оптимизации байт-кода, характерные для понятий и genexps, которые нельзя применить к эквивалентным циклам, но ничего, что обеспечивает действительно массовое ускорение. – user2357112

+0

Darn. Ну, как я уже сказал, я надеюсь, что что-то там полезно. – TigerhawkT3

+0

Ну, я не могу добавить 2 и 3, потому что то, что я читаю, является .txt-файлом случайных чисел. И мне нужно проверить каждый номер, чтобы убедиться, что это просто. Вот почему я проверяю, если это 2 или 3. –

Смежные вопросы