【问题标题】:Map function that needs to be faster需要更快的地图功能
【发布时间】:2015-04-04 05:40:22
【问题描述】:

我正在尝试优化我的代码以在 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)

【问题讨论】:

  • 当你看到 2 或 3 时,为什么要减少合数的计数?
  • 2 和 3 都是质数,但 1 不是。
  • 是的,但如果输入只是两个数字 2 和 3,你见过负的两个合数吗?
  • 没错,我改了。创建了一个跟踪素数的变量,如果读入 2 和 3,只需添加到该变量。
  • 可以读取的最大数字是多少?

标签: python hadoop optimization mapreduce primes


【解决方案1】:

我试图把一切都变成一种理解。理解比原生 Python 代码更快,因为它们访问 C 库。我也省略了对23 的测试,因为您可以在完成循环后手动添加它们。

我几乎可以保证这会有错误,因为我没有你的测试数据和这么大的理解(无论如何对我来说)确实需要测试。从技术上讲,它是单行的,但为了便于阅读,我尝试将其拆分。不过,希望它至少能给你一些想法。

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。

【讨论】:

  • “理解比原生 Python 代码更快,因为它们访问 C 库”——它们不会比等效循环更大程度地做到这一点。我相信有一些特定于理解和基因表达式的字节码优化不能应用于等效循环,但没有什么能提供真正巨大的加速。
  • 该死。好吧,就像我说的,我希望里面有一些有用的东西。
  • 好吧,我不能添加 2 和 3,因为我正在读取的是一个随机数的 .txt 文件。我需要测试每个数字,看看它是否是素数。这就是为什么我要检查它是 2 还是 3。
  • 也许您可以在检查not int(line)%2 之前添加int(line) in (2,3) or?然后,如果它是23,它会立即将其标记为素数,而不检查其他条件(短路)。
猜你喜欢
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 2014-07-19
相关资源
最近更新 更多