Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 排序数组和查找更改-Swift_Arrays_Sorting_Swift_Optimization - Fatal编程技术网

Arrays 排序数组和查找更改-Swift

Arrays 排序数组和查找更改-Swift,arrays,sorting,swift,optimization,Arrays,Sorting,Swift,Optimization,好的,我有一个流,它不断地以很快的速度接收一个数组。这是我想做的 如果数组相同,则不要执行任何操作。如果不同,则创建一个新数组,除已更改的值外,其他值均为nil 例如: 传入数组1:[1,1,1,1] 传入数组2:[1,1,2,1] 我想创建:[nil,nil,2,nil]。仅标记更改 我做了一些有用的东西,我只是觉得没有效率。这是最好的方法吗 var storedArray = [Int](count: 10, repeatedValue: 0) //array for comparing

好的,我有一个流,它不断地以很快的速度接收一个数组。这是我想做的

如果数组相同,则不要执行任何操作。如果不同,则创建一个新数组,除已更改的值外,其他值均为nil

例如:

传入数组1:[1,1,1,1]

传入数组2:[1,1,2,1]

我想创建:[nil,nil,2,nil]。仅标记更改

我做了一些有用的东西,我只是觉得没有效率。这是最好的方法吗

var storedArray = [Int](count: 10, repeatedValue: 0) //array for comparing

func incomingArray(data: [Int]) {
    if data == storedArray {return} //do nothing if its the same
    var tempArray = [Int?](count: 10, repeatedValue: nil) //nil array
    for index in 0...9 {
        if storedArray[index] != data[index] {
            tempArray[index] = data[index] //replace the temp array index               
            }
        }
    //send the completed tempArray to do work  ....

    storedArray = incomingArray //save the stored as the current data
    }
所以上面的代码是有效的。只是效率不高。有更好的主意吗

谢谢

更新1:
我在原来的帖子里搞错了。而不是Int。它们是UInt8

以下是一些加快代码速度的方法:

1) 不要使用
Int?
数组,而是使用普通的
Int
数组,不要将元素标记为
nil
,而是将它们标记为某种特殊的整数值。我不知道那个值是什么,可能0是好的,或者-1,或者
Int.max

更新:上述更改使我的性能提高了约10%

2) 回收结果数组。以便您可以跳过以下代码:

var tempArray = [Int?](count: 10, repeatedValue: nil)
或者更好,让调用者通过
inout
参数传入,这样您就不必担心它的所有权

更新:上述更改使我的性能提高了约50%

以下是此问题中建议的所有版本的代码:

import UIKit
import XCTest

var storedArray1 = [Int?](count: 10, repeatedValue: 0) //array for comparing
func processIncomingArray1(data: [Int]) {
    var tempArray = [Int?](count: 10, repeatedValue: nil) //nil array
    for index in 0...9 {
        if storedArray1[index] != data[index] {
            tempArray[index] = data[index] //replace the temp array index
        }
    }
    storedArray1 = tempArray
}

var storedArray2 = [Int](count: 10, repeatedValue: 0)
func processIncomingArray2(data: [Int]) {
    var tempArray = [Int](count: 10, repeatedValue: Int.max)
    for index in 0...9 {
        if storedArray2[index] != data[index] {
            tempArray[index] = data[index]
        }
    }
    storedArray2 = tempArray
}

var storedArray3 = [Int](count: 10, repeatedValue: Int.max)
func processIncomingArray3(data: [Int], inout result: [Int]) {
    for index in 0...9 {
        if result[index] != data[index] {
            result[index] = data[index]
        }
    }
}

// Given two sequences, return a sequence of 2-tuples (pairs)
public func zip<A: SequenceType, B: SequenceType>(a: A, b: B)
    -> ZipSequence<A, B>
{
    return ZipSequence(a, b)
}

// Lazy sequence of tuples created from values from two other sequences
public struct ZipSequence<A: SequenceType, B: SequenceType>: SequenceType {
    private var a: A
    private var b: B

    public init (_ a: A, _ b: B) {
        self.a = a
        self.b = b
    }

    public func generate() -> ZipGenerator<A.Generator, B.Generator> {
        return ZipGenerator(a.generate(), b.generate())
    }
}

// Generator that creates tuples of values from two other generators
public struct ZipGenerator<A: GeneratorType, B: GeneratorType>: GeneratorType {
    private var a: A
    private var b: B

    public init(_ a: A, _ b: B) {
        self.a = a
        self.b = b
    }

    mutating public func next() -> (A.Element, B.Element)? {
        switch (a.next(), b.next()) {
        case let (.Some(aValue), .Some(bValue)):
            return (aValue, bValue)
        default:
            return nil
        }
    }
}



func differences<T: Equatable>(lhs: [T], rhs: [T]) -> [Int] {
    // indexedPairs is a sequence of (index, (left-hand val, right-hand val))
    let indexedPairs = enumerate(zip(lhs,rhs))
    // the lazy may or may not help here, benchmark to find out...
    return lazy(indexedPairs).filter { (index, pair) in
        // only return different pairs
        pair.0 != pair.1
        }.map {
            // only return the index not the values
            $0.0
        }.array
}

var storedArray4 = [Int](count: 10, repeatedValue: Int.max)
func processIncomingArray4(data: [Int]) {
    let diffs = differences(storedArray4, data)
    if !diffs.isEmpty {
        // send new data and diff indices for further processing
        // then overwrite the old array
        storedArray4 = data
    }
}


func differences5<T: Equatable>(lhs: [T], rhs: [T]) -> [Int] {
    var diffs: [Int] = []
    // still using zip, since this guards against the two
    // arrays being of different sizes - doesn’t seem to
    // impact performance
    for (i,(l,r)) in zip(indices(lhs),zip(lhs,rhs)) {
        if l != r { diffs.append(i) }
    }

    return diffs
}

var storedArray5 = [Int](count: 10, repeatedValue: Int.max)
func processIncomingArray5(data: [Int]) {
    let diffs = differences5(storedArray4, data)
    if !diffs.isEmpty {
        // send new data and diff indices for further processing
        // then overwrite the old array
        storedArray5 = data
    }
}


class StackOverflowTests: XCTestCase {

    func testPerformanceExample1() {
        var data = [1,2,3,4,5,6,7,8,9,10]
        self.measureBlock() {
            for i in 1...100000 {
                processIncomingArray1(data)
            }
        }
    }

    func testPerformanceExample2() {
        var data = [1,2,3,4,5,6,7,8,9,10]
        self.measureBlock() {
            for i in 1...100000 {
                processIncomingArray2(data)
            }
        }
    }

    func testPerformanceExample3() {
        var data = [1,2,3,4,5,6,7,8,9,10]
        self.measureBlock() {
            for i in 1...100000 {
                processIncomingArray3(data, &storedArray3)
            }
        }
    }

    func testPerformanceExample4() {
        var data = [1,2,3,4,5,6,7,8,9,10]
        self.measureBlock() {
            for i in 1...100000 {
                processIncomingArray4(data)
            }
        }
    }

    func testPerformanceExample5() {
        var data = [1,2,3,4,5,6,7,8,9,10]
        self.measureBlock() {
            for i in 1...100000 {
                processIncomingArray5(data)
            }
        }
    }

}
导入UIKit
导入测试
var storedArray1=[Int?](计数:10,重复值:0)//用于比较的数组
func processIncomingArray1(数据:[Int]){
var tempArray=[Int?](计数:10,repeatedValue:nil)//nil数组
对于0…9中的索引{
如果storedArray1[index]!=数据[index]{
tempArray[index]=data[index]//替换临时数组索引
}
}
storedArray1=tempArray
}
var storedArray2=[Int](计数:10,重复值:0)
func processIncomingArray2(数据:[Int]){
var tempArray=[Int](计数:10,repeatedValue:Int.max)
对于0…9中的索引{
如果storedArray2[index]!=数据[index]{
tempArray[索引]=数据[索引]
}
}
storedArray2=tempArray
}
var storedArray3=[Int](计数:10,重复值:Int.max)
func processIncomingArray3(数据:[Int],输入输出结果:[Int]){
对于0…9中的索引{
如果结果[索引]!=数据[索引]{
结果[索引]=数据[索引]
}
}
}
//给定两个序列,返回一个2元组(对)序列
公共职能邮政编码(a:a,b:b)
->拉链序列
{
返回ZipSequence(a、b)
}
//从另外两个序列的值创建的元组的惰性序列
公共结构ZipSequence:SequenceType{
私有变量a:a
私有变量b:b
公共初始化(a:a,b:b){
self.a=a
self.b=b
}
public func generate()->ZipGenerator{
返回ZipGenerator(a.generate(),b.generate())
}
}
//从其他两个生成器创建值元组的生成器
公共结构ZipGenerator:GeneratorType{
私有变量a:a
私有变量b:b
公共初始化(a:a,b:b){
self.a=a
self.b=b
}
修改公共函数next()->(A.Element,B.Element){
开关(a.next(),b.next()){
小格(.Some(aValue),.Some(bValue)):
返回值(aValue,bValue)
违约:
归零
}
}
}
函数差异(左[T],右[T])->[Int]{
//indexedPairs是(索引,(左侧val,右侧val))的序列
让indexedPairs=枚举(zip(左、右))
//懒惰的人可能会也可能不会帮上忙,看看吧。。。
返回lazy(indexedPairs)。在
//只返回不同的对
对.0!=对.1
}.地图{
//只返回索引,不返回值
$0.0
}.数组
}
var storedArray4=[Int](计数:10,重复值:Int.max)
func processIncomingArray4(数据:[Int]){
设差异=差异(storedArray4,数据)
如果!差异是空的{
//发送新数据和差异索引以进行进一步处理
//然后覆盖旧数组
storedArray4=数据
}
}
函数差分5(左[T],右[T])->[Int]{
变量差异:[Int]=[]
//仍然使用zip,因为这可以防止两个
//不同大小的数组-看起来不一样
//冲击性能
对于zip中的(i,(l,r))(索引(lhs),zip(lhs,rhs)){
如果l!=r{diff.append(i)}
}
回差
}
var storedArray5=[Int](计数:10,重复值:Int.max)
func processIncomingArray5(数据:[Int]){
设差异=差异5(storedArray4,数据)
如果!差异是空的{
//发送新数据和差异索引以进行进一步处理
//然后覆盖旧数组
storedArray5=数据
}
}
类StackOverflowTests:XCTestCase{
func testPerformanceExample1(){
var数据=[1,2,3,4,5,6,7,8,9,10]
self.measureBlock(){
因为我有10万美元{
processIncomingArray1(数据)
}
}
}
func testPerformanceExample2(){
var数据=[1,2,3,4,5,6,7,8,9,10]
self.measureBlock(){
因为我有10万美元{
processIncomingArray2(数据)
}
}
}
func测试性能示例3(){
var数据=[1,2,3,4,5,6,7,8,9,10]
self.measureBlock(){
因为我有10万美元{
processIncomingArray3(数据和存储阵列3)
}
}
}
func testPerformanceExample4(){
var数据=[1,2,3,4,5,6,7,8,9,10]
self.measureBlock(){
因为我有10万美元{
processIncomingArray4(数据)
}
}
}
func测试性能示例5(){
var数据=[1,2,3,4,5,6,7,8,9,10]
self.measureBlock(){
因为我有10万美元{
processIncomingArray5(数据)
}
if data == storedArray {return}
func differences<T: Equatable>(lhs: [T], rhs: [T]) -> [Int] {
    // indexedPairs is a sequence of (index, (left-hand val, right-hand val))
    let indexedPairs = enumerate(zip(lhs,rhs))
    // the lazy may or may not help here, benchmark to find out...
    return lazy(indexedPairs).filter { (index, pair) in
        // only return different pairs
        pair.0 != pair.1
    }.map {
        // only return the index not the values
        $0.0
    }.array
}
func incomingArray(data: [Int]) {
    let diffs = differences(storedArray, data)
    if !diffs.isEmpty {
        // send new data and diff indices for further processing
        // then overwrite the old array
        storedArray = data
    }
}
func differences<T: Equatable>(lhs: [T], rhs: [T]) -> [Int] {
    var diffs: [Int] = []
    // still using zip, since this guards against the two
    // arrays being of different sizes - doesn’t seem to
    // impact performance
    for (i,(l,r)) in zip(indices(lhs),zip(lhs,rhs)) {
        if l != r { diffs.append(i) }
    }

    return diffs
}