Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

But really, for most common usages of this logic, I think the sequence-based APIthe sequence-based API would probably be the clearest API to use – as I imagine most use cases will revolve around having to iterate through different permutations.

But really, for most common usages of this logic, I think the sequence-based API would probably be the clearest API to use – as I imagine most use cases will revolve around having to iterate through different permutations.

But really, for most common usages of this logic, I think the sequence-based API would probably be the clearest API to use – as I imagine most use cases will revolve around having to iterate through different permutations.

added 325 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7
extension Array {
    
    /// Reverses the elements of the collection within a given range of indices.
    ///
    /// - Parameter indices: A range of valid indices of the collection,
    ///  the elements of which will be reversed.
    ///
    mutating func reverse(indices: Range<Index>) {
        
        if isEmpty || indices.isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}

The major bottleneck here appears to be with Sequence's first(where:) method. If we take a look at its implementationits implementation, we can see it's implemented as:

A simple fix to this problem is to simply define our own first(where:) method for random-access collections that just uses a for-in loop for random-access collections. This allows us to take advantage of a more performant version of the method, while still allowing for complicated non-random-access collections to have a first(where:) implementation that uses their (potentially) customised forEach(_:) implementation.

extension Array {
    
    mutating func reverse(indices: Range<Index>) {
        
        if isEmpty || indices.isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}

The major bottleneck here appears to be with Sequence's first(where:) method. If we take a look at its implementation, we can see it's implemented as:

A simple fix to this problem is to simply define our own first(where:) method for random-access collections that uses a for-in loop. This allows us to take advantage of a more performant version of the method, while still allowing for complicated non-random-access collections to have a first(where:) implementation that uses their (potentially) customised forEach(_:) implementation.

extension Array {
    
    /// Reverses the elements of the collection within a given range of indices.
    ///
    /// - Parameter indices: A range of valid indices of the collection,
    ///  the elements of which will be reversed.
    ///
    mutating func reverse(indices: Range<Index>) {
        
        if indices.isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}

The major bottleneck here appears to be with Sequence's first(where:) method. If we take a look at its implementation, we can see it's implemented as:

A simple fix to this problem is to define our own first(where:) method that just uses a for-in loop for random-access collections. This allows us to take advantage of a more performant version of the method, while still allowing for complicated non-random-access collections to have a first(where:) implementation that uses their (potentially) customised forEach(_:) implementation.

added 19 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7

This gives me a benchmark time down of ~2.65 seconds (running it with a Swift 3.1 -O build). Here's some improvements we can make to improve uponreduce this time...

extension Array {
    
    mutating func reverse(indices: Range<Index>) {
        
        if isEmpty || indices.isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}

This gives me a benchmark time down of ~2.65 seconds (running it with a Swift 3.1 -O build). Here's some improvements we can make to improve upon this...

extension Array {
    
    mutating func reverse(indices: Range<Index>) {
        
        if isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}

This gives me a benchmark time down of ~2.65 seconds (running it with a Swift 3.1 -O build). Here's some improvements we can make to reduce this time...

extension Array {
    
    mutating func reverse(indices: Range<Index>) {
        
        if isEmpty || indices.isEmpty { return }
        
        var low = indices.lowerBound
        var high = index(before: indices.upperBound)
        
        while low < high {
            swap(&self[low], &self[high])
            formIndex(after: &low)
            formIndex(before: &high)
        }
    }
}
Bounty Ended with 50 reputation awarded by Martin R
added 78 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7
Loading
added 97 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7
Loading
added 13 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7
Loading
added 46 characters in body
Source Link
Hamish
  • 433
  • 4
  • 7
Loading
Source Link
Hamish
  • 433
  • 4
  • 7
Loading