Octave 试图提高Julia代码的执行时间
我需要编写一个代码,使用一个语法和一个规则生成一个字符串。例如,如果规则为“G->[G+G]”,我们将该规则应用于“G”,则结果为字符串“[G+G]”;如果我们将其应用于前面的结果,我们将得到“[[G+G]+[G+G]]”等等。换句话说,它是关于重写公理(规则的左侧)给定次数, 遵守规则 我收到了一段用八度音阶编写的代码,它实现了这个操作(我不会包含代码,因为它有点长,但是如果理解或回答问题需要的话,我会包含)。我需要做的是在Julia中编写一个等价函数;所以我写了这个Octave 试图提高Julia代码的执行时间,octave,julia,grammar,Octave,Julia,Grammar,我需要编写一个代码,使用一个语法和一个规则生成一个字符串。例如,如果规则为“G->[G+G]”,我们将该规则应用于“G”,则结果为字符串“[G+G]”;如果我们将其应用于前面的结果,我们将得到“[[G+G]+[G+G]]”等等。换句话说,它是关于重写公理(规则的左侧)给定次数, 遵守规则 我收到了一段用八度音阶编写的代码,它实现了这个操作(我不会包含代码,因为它有点长,但是如果理解或回答问题需要的话,我会包含)。我需要做的是在Julia中编写一个等价函数;所以我写了这个 function
function generate_developedstring(axiom::ASCIIString, genome::ASCIIString, iterations::Int8)
tic()
developedstring = axiom
for i=1:iterations
developedstring = replace(developedstring, axiom, genome)
end
toc()
return developedstring
end
在我前面写的例子中,axiom是“G”,基因组是“[G+G]”
根据julialang.org出版的《基准时报》,茱莉亚应该比八度快很多,但在这种情况下,八度是茱莉亚的两倍
(我对这两种代码使用了相同的公理、基因组和迭代,并用tic-toc函数测量了时间)
有没有办法让Julia代码更快
编辑:首先,非常感谢大家的评论。我将向您展示给我的八度代码(不是我写的):
关于我使用的Julia版本,它是0.4.7。你还问我需要它跑多快;我只需要尽可能快地编写代码,而八度音阶更快的事实让我觉得我做错了什么。
再次感谢。您能将
基因组指定为规则而不是模式吗?我的意思是,例如genome=ax->“[$ax,$ax]”
比较这两种实现,第一种实现与您的实现相同:
function genstring(axiom::String, genome::String, iter::Int)
str = axiom
for i in 1:iter
str = replace(str, axiom, genome)
end
return str
end
然后使用匿名函数:
genome = ax -> "[$ax,$ax]"
function genstring_(axiom::String, genome, n::Int)
if n < 1
return axiom
end
return genstring_(genome(axiom), genome, n-1)
end
它可以更好地扩展:
julia> @benchmark genstring("G", "[G,G]", 10)
BenchmarkTools.Trial:
memory estimate: 18.00 kb
allocs estimate: 71
--------------
minimum time: 93.569 μs (0.00% GC)
median time: 95.959 μs (0.00% GC)
mean time: 103.429 μs (3.05% GC)
maximum time: 4.216 ms (97.14% GC)
--------------
samples: 10000
evals/sample: 1
time tolerance: 5.00%
memory tolerance: 1.00%
julia> @benchmark genstring_("G", genome, 10)
BenchmarkTools.Trial:
memory estimate: 14.13 kb
allocs estimate: 49
--------------
minimum time: 3.072 μs (0.00% GC)
median time: 3.597 μs (0.00% GC)
mean time: 5.703 μs (29.78% GC)
maximum time: 441.515 μs (98.24% GC)
--------------
samples: 10000
evals/sample: 8
time tolerance: 5.00%
memory tolerance: 1.00%
据我所知,字符串插值不是超快速的,因此可能会有进一步的优化。首先有一些建议:使用@time
宏而不是tic
/toc
/内部函数,并进行两次基准测试,以排除编译时间。如果您在讨论论坛上发布了一个最小的、可运行的示例,那么您可能会在这类性能问题上获得更有用的帮助:Octave代码是否都是一个矢量化调用?如果是的话,那么你不是在比较八度本身。相反,你会将Julia与可能在C中实现的优化良好的函数进行比较。你不应该期望Julia比C做得更好,尽管它通常应该很接近。我花了一些时间在这方面,Julia版本看起来相当快–迭代字符串版本的速度大约与直接递归打印单个字符串的速度一样快,同样,预先分配适当的空间。您可以发布倍频程代码以便我们看到它在做什么吗?假设您的replace
函数每次都制作一个新的副本,那么可以使用该函数的一个变种版本(名为replace!
)来代替,该变种版本可以改变现有对象,从而避免内存分配。为了实现这一点,developedstring
可以有一些填充,以确保它不必在每次迭代时更改大小。replace代码>不存在?因为String
s是不可变的。在Julia v0.6中匿名函数几乎没有性能损失是真的吗?如果是这样的话,那么您的第二个解决方案在Julia的开发副本上会更快。这种性能改进已经在v0.5中发生了。不过,将有一个新的字符串实现。不确定这会对性能产生什么影响。非常感谢,使用匿名函数,程序速度会快得多。
julia> @benchmark genstring("G", "[G,G]", 2)
BenchmarkTools.Trial:
memory estimate: 752.00 bytes
allocs estimate: 15
--------------
minimum time: 745.950 ns (0.00% GC)
median time: 801.067 ns (0.00% GC)
mean time: 1.006 μs (14.30% GC)
maximum time: 50.271 μs (96.63% GC)
--------------
samples: 10000
evals/sample: 119
time tolerance: 5.00%
memory tolerance: 1.00%
julia> @benchmark genstring_("G", genome, 2)
BenchmarkTools.Trial:
memory estimate: 352.00 bytes
allocs estimate: 9
--------------
minimum time: 397.562 ns (0.00% GC)
median time: 414.149 ns (0.00% GC)
mean time: 496.511 ns (13.06% GC)
maximum time: 24.410 μs (97.18% GC)
--------------
samples: 10000
evals/sample: 201
time tolerance: 5.00%
memory tolerance: 1.00%
julia> @benchmark genstring("G", "[G,G]", 10)
BenchmarkTools.Trial:
memory estimate: 18.00 kb
allocs estimate: 71
--------------
minimum time: 93.569 μs (0.00% GC)
median time: 95.959 μs (0.00% GC)
mean time: 103.429 μs (3.05% GC)
maximum time: 4.216 ms (97.14% GC)
--------------
samples: 10000
evals/sample: 1
time tolerance: 5.00%
memory tolerance: 1.00%
julia> @benchmark genstring_("G", genome, 10)
BenchmarkTools.Trial:
memory estimate: 14.13 kb
allocs estimate: 49
--------------
minimum time: 3.072 μs (0.00% GC)
median time: 3.597 μs (0.00% GC)
mean time: 5.703 μs (29.78% GC)
maximum time: 441.515 μs (98.24% GC)
--------------
samples: 10000
evals/sample: 8
time tolerance: 5.00%
memory tolerance: 1.00%