Created
July 24, 2013 06:41
-
-
Save kmsquire/6068488 to your computer and use it in GitHub Desktop.
Code causing heap(?) corruption in julia
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module sp | |
export sortperf, std_sort_tests | |
import Base.Sort: InsertionSort, QuickSort, MergeSort, TimSort, Algorithm, Ordering | |
using DataFrames | |
# rand functions for testing | |
randstr(n::Int) = [randstring() for i = 1:n] | |
randint(n::Int) = rand(1:n,n) | |
randfns = (Type=>Function)[Int => randint, | |
String => randstr, | |
Float32 => x->float32(rand(x)), | |
Float64 => rand] | |
std_types = [Int] | |
sort_algs = [InsertionSort, QuickSort, MergeSort, TimSort] | |
# DataFrame labels | |
labels = ["test_type", "sort_alg", "log_size", "size", "*sort", | |
"\\sort", "/sort", "3sort", "+sort", "~sort", "=sort", "!sort"] | |
# Test algorithm performance on a data vector | |
function sortperf(alg::Algorithm, origdata::Vector, order::Ordering=Sort.Forward; replicates::Int=3, skip_median_killer::Bool=false) | |
srand(1) | |
times = Dict[] # Array of Dicts! | |
n = length(origdata) | |
logn = log2(length(origdata)) | |
rec = {"test_type" => string(eltype(origdata)), | |
"sort_alg" => string(alg)[1:end-5], | |
"log_size" => isinteger(logn) ? int(logn) : logn, | |
"size" => length(origdata)} | |
for rep = 1:replicates | |
print(rep, " ") | |
reptimes = Dict{String, Float64}() | |
## Random | |
data = copy(origdata) | |
gc() | |
if !issorted(data, order) | |
reptimes["*sort"] = @elapsed sort!(data, alg, order) | |
end | |
## Sorted | |
gc() | |
## Reverse sorted | |
reverse!(data) | |
gc() | |
reptimes["\\sort"] = @elapsed sort!(data, alg, order) | |
## Sorted with 3 exchanges | |
for i = 1:3 | |
n1 = rand(1:n) | |
n2 = rand(1:n) | |
data[n1], data[n2] = data[n2], data[n1] | |
end | |
gc() | |
reptimes["3sort"] = @elapsed sort!(data, alg, order) | |
## Sorted with 10 unsorted values at end | |
if length(data) >= 20 | |
for i = 1:10 | |
val = splice!(data, i:i) | |
append!(data, val) | |
end | |
gc() | |
reptimes["+sort"] = @elapsed sort!(data, alg, order) | |
end | |
## Random data with 4 unique values | |
idxs = Int[] | |
for i = 1:4 | |
idx = rand(1:n) | |
while contains(idxs, idx) | |
idx = rand(1:n) | |
end | |
push!(idxs, idx) | |
end | |
vals = data[idxs] | |
data4 = vals[rand(1:4, n)] | |
gc() | |
reptimes["~sort"] = @elapsed sort!(data4, alg, order) | |
## All values equal | |
data1 = data[fill(rand(1:n), n)] | |
gc() | |
reptimes["=sort"] = @elapsed sort!(data1, alg, order) | |
push!(times, merge(rec, reptimes)) | |
end | |
println() | |
times | |
end | |
# run sortperf over a range of data lengths | |
function sortperf(alg::Algorithm, data::Vector, log2range::Ranges, order::Ordering=Sort.Forward; named...) | |
lg2range = filter(x -> 2^x <= length(data), [log2range]) | |
times = Dict[] | |
for logsize in lg2range | |
println(" $logsize") | |
println(named) | |
size = 2^logsize | |
if (alg == InsertionSort && logsize >= 14) | |
println("Skipped") | |
continue | |
end | |
append!(times, sortperf(alg, data[1:size], order; named...)) | |
end | |
times | |
end | |
# Generate a random array and run sortperf | |
function sortperf(alg::Algorithm, T::Type, size::Int, args...; named...) | |
println("Testing $T...") | |
sortperf(alg, randfns[T](size), args...; named...) | |
end | |
# Generate a random array and run sortperf over different ranges of that array | |
function sortperf(alg::Algorithm, T::Type, log2range::Ranges, args...; named...) | |
println("Testing $T...") | |
sortperf(alg, randfns[T](2^last(log2range)), log2range, args...; named...) | |
end | |
# Run sortperf for a number of types | |
function sortperf(alg::Algorithm, types::Vector{DataType}, args...; named...) | |
times = Dict[] | |
for T in types | |
append!(times, sortperf(alg, T, args...; named...)) | |
end | |
times | |
end | |
# Run sortperf on a number of algorithms | |
function sortperf(algs::Vector{Algorithm}, args...; named...) | |
times = Dict[] | |
for alg in algs | |
println("\n$alg\n") | |
append!(times, sortperf(alg, args...; named...)) | |
end | |
times | |
end | |
# Returns a DataFrame version of sortperf output | |
sortperf_df(args...; named...) = DataFrame(sortperf(args...; named...), labels) | |
# Test standard sort functions | |
function std_sort_tests(;sort_algs=sp.sort_algs, types=sp.std_types, range=6:20, replicates=3, | |
lt::Function=isless, by::Function=identity, rev::Bool=false, order::Ordering=Sort.Forward, | |
save::Bool=false, prefix="sortperf") | |
sort_times = sortperf_df(sort_algs, std_types, range, Sort.ord(lt,by,rev,order); replicates=replicates) | |
sort_times | |
end | |
end # module sp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment