编辑:好一点的性能 - 见代码注释
这是博古米尔卡明斯基的ANS WER其中我试图避免计算长度(*),如果它不是必要的:
function shufflefast2(s::String)
ss = sizeof(s)
local l
for l in 1:ss
#if ((codeunit(s,l) & 0xc0) == 0x80)
if codeunit(s,l)>= 0x80 # edit (see comments bellow why)
break
end
end
ss == l && return String(shuffle!(copy(Vector{UInt8}(s))))
v = Vector{Int}(ss)
i = 1
l = 0
while i<ss
l += 1
v[l] = i
i = nextind(s, i)
end
v[l+1] = ss+1 # edit - we could do this because ss>l
p = pointer(s)
u = Vector{UInt8}(ss)
k = 1
for i in randperm(l)
# for j in v[i]:(i == l ? ss : v[i+1]-1)
for j in v[i]:v[i+1]-1 # edit we could do this because v[l+1] is defined (see above)
u[k] = unsafe_load(p, j)
k += 1
end
end
String(u)
end
实施例定时ASCII字符串:
julia> srand(1234);@btime for i in 1:100 danshufflefast("test") end
19.783 μs (500 allocations: 34.38 KiB)
julia> srand(1234);@btime for i in 1:100 bkshufflefast("test") end
10.408 μs (300 allocations: 18.75 KiB)
julia> srand(1234);@btime for i in 1:100 shufflefast2("test") end
10.280 μs (300 allocations: 18.75 KiB)
差过小,有时bkshufflefast更快。性能必须相同。整个长度必须被计数并且有相同的分配。为Unicode字符串
实施例定时:
julia> srand(1234);@btime for i in 1:100 danshufflefast(s) end
24.964 μs (500 allocations: 42.19 KiB)
julia> srand(1234);@btime for i in 1:100 bkshufflefast(s) end
20.882 μs (400 allocations: 37.50 KiB)
julia> srand(1234);@btime for i in 1:100 shufflefast2(s) end
19.038 μs (400 allocations: 40.63 KiB)
shufflefast2是一个小但明显更快这里。比丹的解决方案多一点分配比博略米尔的功能和少一些的分配。
(*) - 我一点希望,在朱莉娅的字符串实施将在未来和长度速度可能会更快,比现在。
'join(collect(s)[randperm(length(s))])' –
至少第二种方式有unicode问题。 '函数样例(s :: String)join(getindex([i for s in],randperm(length(s))))end; sample(“ďaľšý”)似乎也适用于unicode。 (但丹的解决方案更好!:) – Liso
如果您知道这是一个ASCII字符串:'[randperm(end)]''。否则:'加入(shuffle!(collect(s)))'。也许是一个很好的写法:'s | collect |> shuffle! |>加入'。 – DNF