【问题标题】:Python Fast conversion from int to stringPython从int到string的快速转换
【发布时间】:2018-06-16 13:01:21
【问题描述】:

我正在用 python 解决大量阶乘,并发现当我计算完阶乘时,转换为字符串以保存到文件需要相同的时间。我试图找到一种将 int 转换为字符串的快速方法。我将举一个计算和int转换时间的例子。我正在使用通用的 a = str(a) 但我觉得有更好的方法,比如使用缓冲区或库。

前:

求解 100,000 个阶乘 = 456,574 个数字

计算时间:6.36 秒

转换时间:5.20 秒

如果您有任何问题/解决方案,请告诉我!任何事情都会有所帮助。

import time

factorial = 1

print(" ")

one = int(input("lower  = "))
two = int(input("higher = "))

start = time.time()

for x in range(one,two + 1):
        factorial = factorial * two
        two = two - 1

end = time.time()

print("DONE! ")
print(end - start, "Seconds to compute")

start = time.time()

factorial = str(factorial)

f = open('Ans_1.txt','w')
f.write(factorial)
f.close()

end = time.time()

print(end - start, "Seconds to convert and save")

print(len(factorial), "Digets")

【问题讨论】:

  • 我们也需要查看您的代码。考虑将int 转换为strstr(int) 最快。但绝对可以在您的阶乘逻辑中改进一些东西
  • @MoinuddinQuadri 我不确定他的阶乘逻辑可以改进多少。我正在使用 math.factorial(100000) 获得类似的运行时
  • 如果 OP 使用的是math.factorial,那么我怀疑 Python 2.7 可以做些什么。在 Python 3 中它会相对更快。这是Why is math.factorial much slower in Python 2.x than 3.x? 可能感兴趣的讨论
  • 我认为没有更快的方法将其保存到字符串中,因为这是内置的方法。 @chrisz:math.factorial(100000) 比在 Python 3 中使用此代码快大约 20 倍。我已经尝试了 30 多种不同的算法,试图获得比 math 过去更快的时间,但最终放弃了。如果 OP 想让这段代码更快,我建议尽量减少涉及大量数字的步骤。存储大数字需要更多时间来存储小数字。
  • 试试 pypy :D

标签: python string python-2.7 type-conversion converter


【解决方案1】:

你可以试试gmpy2x.digits([base])。

import time
from gmpy2 import mpz


x = 123456789**12345

start = time.time()
python_str = str(x)
end = time.time()
print(end - start, "Python conversion time")

r = mpz(x)
start = time.time()
gmpy2_str = r.digits()
end = time.time()
print(end-start, "gmpy2 conversion time")

以上测试输出:

1.0336394309997559 Python转换时间

0.03306150436401367 gmpy2转换时间

【讨论】:

  • gmpy2 也有一个非常快的阶乘函数。在我的电脑上str(math.factorial(100000)) 需要约 2.5 秒。 str(gmpy2.fac(100000)) 只需要 ~0.03 秒。而str(gmpy2.fac(1000000)) 需要约 0.7 秒。
【解决方案2】:

这段代码更快(但还不够!:D)

结果:

╔═══╦════════════╦═════════════╦══════════════╦═══════════════════╗
║   ║ Count      ║ Compute(s)  ║  Convert(s)  ║  M.T Convert(s)   ║
╠═══╬════════════╬═════════════╬══════════════╬═══════════════════╣
║ 1 ║ 100,000    ║    2.68     ║     3.85     ║        2.81       ║
║ 2 ║ 250,000    ║   21.17     ║     39.83    ║       21.09       ║
╚═══╩════════════╩═════════════╩══════════════╩═══════════════════╝

无论如何,我认为使用多线程可以更快地做到这一点。

进口时间 导入数学 导入线程

res_dict = {}

def int_str(threadID, each_thread, max_thread):
    if threadID == 1 :
        res_dict[threadID] = (str(factorial // 10 ** (each_thread * (max_thread - 1))))
    elif threadID == max_thread:
        res_dict[threadID] = (str(int(factorial % 10 ** (each_thread * 1))))
    else: 
        tmp = (factorial % 10 ** (each_thread * (max_thread - threadID + 1))) // 10 ** (each_thread * (max_thread - threadID))
        pre = "0" * ((digits // max_thread) - (math.floor(math.log10(tmp))+1))
        res_dict[threadID] = (pre + str(int(tmp)))

factorial = 1

print(" ")

def fact(a,b):
    if b == 1:
        return 1
    else:
        return a * fact(a,b-1)

one = int(input("lower  = "))
two = int(input("higher = "))

start = time.time()

for x in range(one,two + 1):
        factorial = factorial * two
        two = two - 1

end = time.time()

print("DONE! ")
print(end - start, "Seconds to compute")


start = time.time()

digits = math.floor(math.log10(factorial))+1

max_thread      = 3
each_thread     = digits // max_thread

tr = []

for item in range(1, max_thread + 1):
    t = threading.Thread(target=int_str, args=(item, each_thread, max_thread))
    t.start()
    tr.append(t)


for item in tr:
    item.join()

last_res = ''

for item in sorted(res_dict):
    if item != max_thread:
        last_res += res_dict[item]
    else:
        last_res += ("0" * (digits - len(last_res) - len(res_dict[item]))) + res_dict[item]


f = open('Ans_2.txt','w')
f.write(last_res)
f.close()


end = time.time()
print(end - start, "Seconds to convert and save")

print(digits, "Digets")

更新:

只需使用pypy 运行您的代码,它的速度非常快!

╔═══╦════════════╦═════════════╦══════════════╦═══════════════════╗
║   ║ Count      ║ Compute(s)  ║  Convert(s)  ║ pypy Convert(s)   ║
╠═══╬════════════╬═════════════╬══════════════╬═══════════════════╣
║ 1 ║ 100,000    ║    2.98     ║     3.85     ║        0.79       ║
║ 2 ║ 250,000    ║   25.83     ║     39.83    ║        7.17       ║
╚═══╩════════════╩═════════════╩══════════════╩═══════════════════╝

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 2015-05-11
    相关资源
    最近更新 更多