using NullableArrays
using DataArrays
using StatsBase

srand(1)
N = 5_000_000

function profile_stats_methods()
    A = rand(N)
    B = rand(Bool, N)
    X = NullableArray(A)
    Y = NullableArray(A, B)
    D = DataArray(A)
    E = DataArray(A, B)

    profile_mean(A, X, D, Y, E)
    profile_var(A, X, D, Y, E)
    nothing
end

function profile_mean(A, X, D, Y, E)
    W = WeightVec(rand(N))

    mean(A)
    println("Method: mean(A) (0 missing entries)")
    print("  for Array{Float64}:          ")
    @time(mean(A))
    mean(X)
    print("  for NullableArray{Float64}:  ")
    @time(mean(X))
    mean(D)
    print("  for DataArray{Float64}:      ")
    @time(mean(D))
    println()

    mean(Y, skipnull=false)
    println("Method: mean(A) (~half missing entries, skip=false)")
    print("  for NullableArray{Float64}:  ")
    @time(mean(Y, skipnull=false))
    mean(E, skipna=false)
    print("  for DataArray{Float64}:      ")
    @time(mean(E, skipna=false))
    println()

    mean(Y, skipnull=true)
    println("Method: mean(A) (~half missing entries, skip=true)")
    print("  for NullableArray{Float64}:  ")
    @time(mean(Y, skipnull=true))
    mean(E, skipna=true)
    print("  for DataArray{Float64}:      ")
    @time(mean(E, skipna=true))
    println()

    mean(A, W)
    println("Method: mean(A, w::WeightVec{W, V}) (0 missing entries, V<:Array)")
    print("  for Array{Float64}:          ")
    @time(mean(A, W))
    mean(X, W)
    print("  for NullableArray{Float64}:  ")
    @time(mean(X, W))
    mean(D, W)
    print("  for DataArray{Float64}:      ")
    @time(mean(D, W))
    println()

    println("Method: mean(A, W::WeightVec) (~half missing entries, skip=false)")
    mean(Y, W, skipnull=false)
    print("  for NullableArray{Float64}:  ")
    @time(mean(Y, W, skipnull=false))
    mean(E, W, skipna=false)
    print("  for DataArray{Float64}:      ")
    @time(mean(E, W, skipna=false))
    println()

    println("Method: mean(A, W::WeightVec) (~half missing entries, skip=true)")
    mean(Y, W, skipnull=true)
    print("  for NullableArray{Float64}:  ")
    @time(mean(Y,  W, skipnull=true))
    mean(E, W, skipna=true)
    print("  for DataArray{Float64}:      ")
    @time(mean(E, W, skipna=true))
    println()
end

function profile_var(A, X, D, Y, E)
    mu = mean(A)
    mu2 = mean(X, skipnull=true)

    varm(A, mu)
    println("Method: varm(A, mu) (0 missing entries)")
    print("  for Array{Float64}:          ")
    @time(varm(A, mu))
    println("                                  ", varm(A, mu))
    varm(X, mu)
    print("  for NullableArray{Float64}:  ")
    @time(varm(X, mu))
    varm(D, mu)
    print("  for DataArray{Float64}:      ")
    @time(varm(D, mu))
    println()

    varm(Y, mu; skipnull=false)
    println("Method: varm(A, mu) (~half missing entries, skip=false)")
    print("  for NullableArray{Float64}:  ")
    @time(varm(Y, mu; skipnull=false))
    varm(E, mu; skipna=false)
    print("  for DataArray{Float64}:      ")
    @time(varm(E, mu; skipna=false))
    println()

    varm(Y, mu; skipnull=true)
    println("Method: varm(A, mu) (~half missing entries, skip=true)")
    print("  for NullableArray{Float64}:  ")
    @time(varm(Y, mu; skipnull=true))
    varm(E, mu; skipna=true)
    print("  for DataArray{Float64}:      ")
    @time(varm(E, mu; skipna=true))
    println()
end
