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

[SE-0225] Implementation of isMultiple for BinaryInteger. #18689

Merged
merged 2 commits into from
Sep 4, 2018

Conversation

stephentyrone
Copy link
Contributor

@stephentyrone stephentyrone commented Aug 14, 2018

@stephentyrone
Copy link
Contributor Author

@swift-ci please test.

@stephentyrone
Copy link
Contributor Author

@swift-ci please smoke test

@@ -560,7 +564,7 @@ tests.test("truncatingIfNeeded") {

tests.test("Parsing/LosslessStringConvertible") {
func _toArray<T: LosslessStringConvertible>(_ text: String) -> [T] {
return text.split(separator: " ").map { T(String($0)) }.flatMap { $0 }
return text.split(separator: " ").map { T(String($0)) }.compactMap { $0 }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor update to silence warning while we're here.

@inlinable
public func isMultiple(of other: Self) -> Bool {
// Nothing but zero is a multiple of zero.
if other == 0 { return self == 0 }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use of guard for an early return?

Copy link
Contributor Author

@stephentyrone stephentyrone Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I think it reads a lot more clearly as an if, because it avoids the double-negative.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense! @stephentyrone thanks for your response 😉

@stephentyrone
Copy link
Contributor Author

@swift-ci Please smoke test

@stephentyrone
Copy link
Contributor Author

@swift-ci Please smoke test.

@@ -39,8 +39,7 @@ import StdlibUnittest
/// integer type. Nesting `DoubleWidth` instances, in particular, may result in
/// undesirable performance.
public struct DoubleWidth<Base : FixedWidthInteger>
where Base.Magnitude : UnsignedInteger,
Base.Words : Collection, Base.Magnitude.Words : Collection {
where Base.Words : Collection, Base.Magnitude.Words : Collection {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unrelated PR a few weeks ago removed the need for the .Magnitude : UnsignedInteger conformance. Removing it to get rid of warning in tests.

@@ -282,7 +281,7 @@ extension DoubleWidth.Words: Collection {

public func index(after i: Index) -> Index {
switch i._value {
case let .low(li) where Base.bitWidth < UInt.bitWidth:
case .low where Base.bitWidth < UInt.bitWidth:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is also just cleaning up some noise.

@stephentyrone
Copy link
Contributor Author

SE-0225 has been approved with revisions. I will update this PR to match what was approved, but I'm not going to pursue merging it until two much more involved changes to integer protocols land, to avoid causing any merge issues for them:

A default implementation is provided for FixedWidthInteger. Very basic test coverage included as well.
@stephentyrone stephentyrone changed the title [DNM] Implementation of isEven/isOdd/isMultiple for BinaryInteger. [SE-0225] Implementation of isMultiple for BinaryInteger. Sep 3, 2018
@stephentyrone
Copy link
Contributor Author

@swift-ci please test

@stephentyrone
Copy link
Contributor Author

@natecook1000 Either notes on documentation or a follow-on commit appreciated.

@swift-ci
Copy link
Contributor

swift-ci commented Sep 3, 2018

Build failed
Swift Test Linux Platform
Git Sha - eaa9f82c5036aa3839eae6ecae0ab47ed3b5c63c

@swift-ci
Copy link
Contributor

swift-ci commented Sep 3, 2018

Build failed
Swift Test OS X Platform
Git Sha - eaa9f82c5036aa3839eae6ecae0ab47ed3b5c63c

@stephentyrone
Copy link
Contributor Author

@swift-ci please benchmark

@swift-ci
Copy link
Contributor

swift-ci commented Sep 3, 2018

Build comment file:

Performance: -O

TEST OLD NEW DELTA SPEEDUP
Regression
EqualStringSubstring 45 49 +8.9% 0.92x
CStringLongAscii 3280 3551 +8.3% 0.92x
Improvement
StringHashing_abnormal 1563 1358 -13.1% 1.15x
StringHashing_longSharedPrefix 8106 7436 -8.3% 1.09x
StringHashing_fastPrenormal 8812 8131 -7.7% 1.08x

Code size: -O

TEST OLD NEW DELTA SPEEDUP
Regression
BinaryFloatingPointConversionFromBinaryInteger.o 12066 12306 +2.0% 0.98x

Performance: -Osize

TEST OLD NEW DELTA SPEEDUP
Improvement
StringHashing_abnormal 1540 1337 -13.2% 1.15x
StringHashing_longSharedPrefix 8053 7439 -7.6% 1.08x

Code size: -Osize

TEST OLD NEW DELTA SPEEDUP
Regression
BinaryFloatingPointConversionFromBinaryInteger.o 11778 12018 +2.0% 0.98x

Performance: -Onone

TEST OLD NEW DELTA SPEEDUP
Regression
PrefixArrayLazy 31392 34843 +11.0% 0.90x
DropFirstArrayLazy 31766 34857 +9.7% 0.91x
SortStringsUnicode 2713 2924 +7.8% 0.93x (?)
Improvement
StringHashing_abnormal 1610 1456 -9.6% 1.11x
ArrayOfPOD 859 783 -8.8% 1.10x (?)
How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false alarms. Unexpected regressions which are marked with '(?)' are probably noise. If you see regressions which you cannot explain you can try to run the benchmarks again. If regressions still show up, please consult with the performance team (@eeckstein).

Hardware Overview
  Model Name: Mac Pro
  Model Identifier: MacPro6,1
  Processor Name: 12-Core Intel Xeon E5
  Processor Speed: 2.7 GHz
  Number of Processors: 1
  Total Number of Cores: 12
  L2 Cache (per Core): 256 KB
  L3 Cache: 30 MB
  Memory: 64 GB

// Nothing but zero is a multiple of zero.
if other == 0 { return self == 0 }
// Special case to avoid overflow on .min / -1 for signed types.
if Self.isSigned && self == .min && other == -1 { return true }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be curious if performance changes if the two conditionals were replaced with a check of the magnitude, i.e. return other.magnitude <= 1 || self % other == 0...

Copy link
Contributor Author

@stephentyrone stephentyrone Sep 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For concrete types, there should basically be no difference in the face of optimization. We should be able to teach the optimizer to have only a single test on the fast-path, but that's follow-on work after the API is in.

@stephentyrone
Copy link
Contributor Author

@swift-ci please smoke test

@stephentyrone stephentyrone merged commit c1f25e0 into swiftlang:master Sep 4, 2018
@stephentyrone stephentyrone deleted the even-odd-integers branch September 4, 2018 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants