Files
swift-mirror/stdlib/unittest/Statistics.swift
Dmitri Hrybenko 3a04e0809f stdlib: add a function to squeeze a number in a given range from a hash value
This function mixes the bits in the hash value, which improves Dictionary
performance for keys with bad hashes.

PrecommitBenchmark changes with greater than 7% difference:

``````````Dictionary2`,```1456.00`,```1508.00`,```1502.00`,````624.00`,````607.00`,````592.00`,`864.00`,``145.9%
``````````Dictionary3`,```1379.00`,```1439.00`,```1408.00`,````585.00`,````567.00`,````552.00`,`827.00`,``149.8%
````````````Histogram`,````850.00`,````849.00`,````851.00`,```1053.00`,```1049.00`,```1048.00`,`199.00`,``-19.0%
````````````````Prims`,```1999.00`,```2005.00`,```2018.00`,```1734.00`,```1689.00`,```1701.00`,`310.00`,```18.4%
``````````StrSplitter`,```2365.00`,```2334.00`,```2316.00`,```1979.00`,```1997.00`,```2000.00`,`337.00`,```17.0%
```````````````TwoSum`,```1551.00`,```1568.00`,```1556.00`,```1771.00`,```1741.00`,```1716.00`,`165.00`,```-9.6%

Regressions are in benchmarks that use `Int` as dictionary key: we are just
doing more work than previously (hashing an `Int` was an identity function).

rdar://17962402


Swift SVN r21142
2014-08-12 12:02:26 +00:00

69 lines
1.9 KiB
Swift

import Darwin
public func rand32() -> UInt32 {
return arc4random()
}
public func rand64() -> UInt64 {
return (UInt64(arc4random()) << 32) | UInt64(arc4random())
}
public func randInt() -> Int {
#if arch(i386) || arch(arm)
return Int(Int32(bitPattern: rand32()))
#elseif arch(x86_64) || arch(arm64)
return Int(Int64(bitPattern: rand64()))
#else
fatalError("unimplemented")
#endif
}
public func randArray64(count: Int) -> ContiguousArray<UInt64> {
var result = ContiguousArray<UInt64>(count: count, repeatedValue: 0)
for i in indices(result) {
result[i] = rand64()
}
return result
}
/// For a given p-value, returns the critical chi-square value for
/// a distribution with 1 degree of freedom.
func _chiSquaredUniform1DFCritical(pValue: Double) -> Double {
if abs(pValue - 0.05) < 0.00001 { return 0.00393214 }
if abs(pValue - 0.02) < 0.00001 { return 0.000628450 }
if abs(pValue - 0.01) < 0.00001 { return 0.000157088 }
if abs(pValue - 0.007) < 0.00001 { return 0.000076971 }
if abs(pValue - 0.005) < 0.00001 { return 0.0000392704 }
if abs(pValue - 0.003) < 0.00001 { return 0.0000141372 }
if abs(pValue - 0.002) < 0.00001 { return 6.2832e-6 }
if abs(pValue - 0.001) < 0.00001 { return 1.5708e-6 }
fatalError("unknown value")
}
/// Perform chi-squared test for a discrete uniform distribution with
/// 2 outcomes.
public func chiSquaredUniform2(
trials: Int, observedACount: Int, pValue: Double
) -> Bool {
func square(x: Double) -> Double {
return x * x
}
let expectedA = 0.5
let expectedB = 0.5
let observedA = Double(observedACount) / Double(trials)
let observedB = 1.0 - observedA
let chiSq =
square(observedA - expectedA) / expectedA +
square(observedB - expectedB) / expectedB
if chiSq > _chiSquaredUniform1DFCritical(pValue) {
println("chi-squared test failed: \(trials) \(observedACount) \(chiSq)")
return false
}
return true
}