Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-12716] The "let-accepting" withUnsafeBytes(of: _:) added by SE-0205 is sometimes much slower than the var-taking old version #55161

Closed
jepers opened this issue May 1, 2020 · 2 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. performance

Comments

@jepers
Copy link

jepers commented May 1, 2020

Previous ID SR-12716
Radar rdar://problem/62895082
Original Reporter @jepers
Type Bug
Status Resolved
Resolution Duplicate
Environment

Default toolchain of Xcode 11.4.1
macOS 10.15.4

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee @eeckstein
Priority Medium

md5: 1a81c1cec9ebced6640e3ddcf5790c34

Issue Description:

Compiling (release build / -O) and running the following program will print:

old: (time: 0.056757071, checksum: 49)
new: (time: 0.739603768, checksum: 3)
old: (time: 0.060270201, checksum: 229)
new: (time: 0.755338226, checksum: 193)
old: (time: 0.057523741, checksum: 125)
new: (time: 0.732603931, checksum: 133)
old: (time: 0.059334589, checksum: 151)
new: (time: 0.737117362, checksum: 45)

Note that `new` is slower than `old`.
The `new` function is using the let-taking variant of `withUnsafeBytes`, added in SE-0205.

I guess this is not expected behavior (the slow down as compared with the old var-taking `withUnsafeBytes`)?

(If `_E.lut` is smaller, eg only two `UInt64` values, they will be equally fast.)

Context: https://forums.swift.org/t/optimal-way-to-create-a-static-lookup-table/36011/10



import Foundation


func old(_ index: UInt8) -> UInt8 {
  enum _E {
    static let x: UInt64 = 0x6363636363636363
    static var lut: (
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64
      ) = (x, x, x, x, x, x, 0x0706050403020100, 0x6363636363630908,
           0x630f0e0d0c0b0a63, x, x, x, 0x630f0e0d0c0b0a63, x, x, x,
           x, x, x, x, x, x, x,x, x, x, x, x, x, x, x, x)
  }
  let i = Int(truncatingIfNeeded: index)
  return withUnsafeBytes(of: &_E.lut) { $0[i] }
}


func new(_ index: UInt8) -> UInt8 {
  enum _E {
    static let x: UInt64 = 0x6363636363636363
    static let lut: (
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64,
      UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64
      ) = (x, x, x, x, x, x, 0x0706050403020100, 0x6363636363630908,
           0x630f0e0d0c0b0a63, x, x, x, 0x630f0e0d0c0b0a63, x, x, x,
           x, x, x, x, x, x, x,x, x, x, x, x, x, x, x, x)
  }
  let i = Int(truncatingIfNeeded: index)
  return withUnsafeBytes(of: _E.lut) { $0[i] }
}


func test(_ fn: (UInt8) -> UInt8) -> (time: Double, checksum: UInt8) {
  let randomBytes = (0 ..< 1024).map { _ in UInt8.random(in: 0 ... 255) }
  var cs: UInt8 = 0
  let t0 = DispatchTime.now().uptimeNanoseconds
  for i in 0 ..< 100_000_000 {
    let ascii = randomBytes[i & 1023]
    let v = fn(ascii)
    cs &+= v
  }
  let t1 = DispatchTime.now().uptimeNanoseconds
  return (time: Double(t1-t0)/1e9, checksum: cs)
}


func performTests() {
  for _ in 0 ..< 4 {
    print("old:", test(old))
    print("new:", test(new))
  }
}
performTests()
@beccadax
Copy link
Contributor

beccadax commented May 5, 2020

@swift-ci create

@eeckstein
Copy link
Member

This is a duplicate of https://bugs.swift.org/browse/SR-12289

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. performance
Projects
None yet
Development

No branches or pull requests

4 participants