You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This (.ulpOfOne) is just one particular example (of a static read-only computed property that should clearly be a constant that shouldn't have to be recalculated every time), and I guess there are many other similar cases.
import Security
import QuartzCore
//-----------------------------------------------------------------------------
// The static property .ulpOfOne is unnecessarily slow (as it seems to perform
// actual function calls to Double(1).ulp on every access). The test() func
// below is almost 5 times faster when setting usingMyUlpOfOne to true.
//-----------------------------------------------------------------------------
let usingMyUlpOfOne = false
extension Double {
static let myUlpOfOne = Double.ulpOfOne
init(unitRange i: UInt64) {
let uoo = usingMyUlpOfOne ? Double.myUlpOfOne : Double.ulpOfOne
self = Double(i >> Double.exponentBitCount) * (uoo / 2.0)
}
}
func unsafeRandomBitPatternElements<T>(count: Int) -> [T]
where T: ExpressibleByIntegerLiteral
{
var a = [T](repeating: 0, count: count)
let r = SecRandomCopyBytes(nil, count * MemoryLayout<T>.stride, &a)
precondition(r == errSecSuccess)
return a
}
func test() {
for _ in 0 ..< 10 {
var sum = Double(0)
let a: [UInt64] = unsafeRandomBitPatternElements(count: 100_000_000)
let t0 = CACurrentMediaTime()
for e in a { sum += Double(unitRange: e) }
let t1 = CACurrentMediaTime()
print("time:", t1 - t0, "seconds, ( sum:", sum, ")")
}
}
print("usingMyUlpOfOne == \(usingMyUlpOfOne):")
test()
//-----------------------------------------------------------------------------
// Example output when run on my MBP late 2013, dev snapshot 2018-01-30:
//-----------------------------------------------------------------------------
//
// usingMyUlpOfOne == false:
// time: 0.506870910001453 seconds, ( sum: 49998178.5861357 )
// time: 0.508704126987141 seconds, ( sum: 50000915.5541131 )
// time: 0.48335500099347 seconds, ( sum: 50002202.6118007 )
// time: 0.490296787000261 seconds, ( sum: 49997649.5106063 )
// time: 0.502311271004146 seconds, ( sum: 49998730.1718012 )
// time: 0.487179237010423 seconds, ( sum: 50001758.3728186 )
// time: 0.530522076995112 seconds, ( sum: 49998896.5738505 )
// time: 0.524156589992344 seconds, ( sum: 50002229.7349948 )
// time: 0.515008457994554 seconds, ( sum: 50001545.8855311 )
// time: 0.50125320898951 seconds, ( sum: 49999437.9996973 )
//
//-----------------------------------------------------------------------------
//
// usingMyUlpOfOne == true:
// time: 0.122320255992236 seconds, ( sum: 49998913.4932828 )
// time: 0.113033984991489 seconds, ( sum: 50000117.6091672 )
// time: 0.111723182984861 seconds, ( sum: 50002081.104568 )
// time: 0.111441375978757 seconds, ( sum: 49997609.1379723 )
// time: 0.111161193985026 seconds, ( sum: 49998541.0318086 )
// time: 0.121517223014962 seconds, ( sum: 49994113.287431 )
// time: 0.116348965995712 seconds, ( sum: 50003603.4877935 )
// time: 0.112562206981238 seconds, ( sum: 49998787.9100643 )
// time: 0.116928763978649 seconds, ( sum: 50003593.6316356 )
// time: 0.111437907005893 seconds, ( sum: 49999608.8038312 )
//
//-----------------------------------------------------------------------------
Is this (eg .ulpOfOne being slow) because of a missing but possible optimization or can't the compiler know that the static computed property need only be actually computed once?
Perhaps Swift needs "pure" or something for it to be knowable?
The text was updated successfully, but these errors were encountered:
We don't want to cache the value because that would mean allocating space for another global variable in the runtime. But we ought to be able to precompute the value, making the getter a simple return.
Additional Detail from JIRA
md5: 86c403574f9bbd5ddc0f4a55ee58a099
Issue Description:
This (.ulpOfOne) is just one particular example (of a static read-only computed property that should clearly be a constant that shouldn't have to be recalculated every time), and I guess there are many other similar cases.
Is this (eg .ulpOfOne being slow) because of a missing but possible optimization or can't the compiler know that the static computed property need only be actually computed once?
Perhaps Swift needs "pure" or something for it to be knowable?
The text was updated successfully, but these errors were encountered: