我是nim的新手,但是想用它来写函数在python中使用。我正在使用 nimpy
和 nimporter
将 nim 函数导入 python。
python中的这个函数:
def pcompare(a, b):
letters = []
for i, letter in enumerate(a):
if letter != b[i]:
letters.append(f'{letter}{i}{b[i]}')
return letters
返回字符串 a
中的字符与字符串 b
中的字符不匹配的情况列表。
我在 nim 中写了同样的函数:
compare.nim
import strformat
import nimpy
proc compare(a, b: string): seq[string] {.exportpy.} =
for i, letter in a:
if letter != b[i]:
result.add(fmt"{letter}{i}{b[i]}")
我可以导入到 python: import nimporter;导入比较;
这些函数生成与 python 代码相同的输出。
但是nim函数比python代码慢很多!
a = 'aaaa' * 1000000
b = 'bbba' * 1000000
s = time.perf_counter()
ptest = pcompare(a, b)
e = time.perf_counter()
print(e - s)
s = time.perf_counter()
ntest = compare.compare(a, b)
e = time.perf_counter()
print(e - s)
output:
python: 1.2781826159916818
nim: 3.607558835996315
任何精通 nim 或其他编译语言的人都可以解释为什么会出现这种情况,并可能建议改进我的 nim 代码吗?
非常感谢所有评论!
谢谢, 威廉
最佳答案
这是一个没有释放开关的经典编译示例。如果您阅读编译 Nim 模块时的输出,您应该会看到如下一行:
提示:gc: refc;线程:开; opt: none (DEBUG BUILD, '-d:release' 生成更快的代码)
使用 -d:release
编译对于在 Nim 中获得良好的速度至关重要。根据您正在做的事情,您还可以使用 -d:danger
获得更多(减少运行时检查),并且根据工作量,尝试新的 也可能会有所帮助-- mm:arc
内存管理模式。
让我们比较一些数字,在我的机器上,您提供的代码给出了这些结果:
0.9097748600001978
5.580064230000062
哦不,甚至比你的数字还要糟糕,不是很好!但是如果我们打开 -d:release
开关,潮流就会转向:
0.9215690670002914
0.5742033299998184
使用 -d:danger
又会带来一点提升(与我的测试中的更多样本相比,它始终稍快一些):
0.9454311069998766
0.5695095589999255
ARC 对这种特殊的工作负载没有帮助,LTO 也没有,但是这两者在其他方面可能表现更好。一般来说,您可以做很多事情来加速 Nim,但到目前为止,最简单、最有效的方法是打开发布构建。
关于python - 在 nim 中比较两个字符串的函数比 python 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72263721/