EDIT:少し良いパフォーマンス - 参照コードが
コメントこれはBogumilカミンスキーの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は明らかに速く、ここで少ししかしです。 Bogumilの機能よりも少し多く割り当てられ、Danのソリューションよりも割り当てが少し少なくなっています。
(*) - JuliaでのString実装が将来的に早くなり、長さが今よりもはるかに早くなることを少し希望します。
'join(s)[randperm(length)(s)])' –
少なくとも2番目の方法はユニコードに問題があります。関数サンプル(s :: String)join(getindex([i in i]、randperm(length(s))))end;サンプル( "ďaľšý")はユニコードでも動作するように見える。 (でもダンの方がいいです:) – Liso
それはASCII文字列であるという事実を知っているなら 's [randperm(end)]'です。それ以外の場合は、 'join(shuffle!(collect(s)))'を実行します。そして、おそらくこれを書いてみるといいでしょう: 's |> collect |> shuffle! |> join'。 – DNF