Swift数组性能问题?

我不确定是否有问题,所以我只是把它写下来。 我正在iphone 5s上使用swift,xcode 7.2开发。 并使用NSDate.timeIntervalSinceReferenceDate()计算执行时间

我创建了2个数组,其中一个拥有20万个元素,另一个拥有20个元素,并尝试随机访问其元素。 访问大型网站的元素几乎慢了55倍! 我知道它更大,但不是这个O(1)?

我也尝试了相同的Java和访问速度是相同的大,小阵列。

从苹果文档中的CFArrayheader ,我发现这个:

在数组中的特定索引处访问任何值最差为O(log n),但通常应为O(1)。

但它认为这不能根据我测试的数字来判断。

我知道我没有做出大的测试或任何特别的事情,但事实上,它没有工作真的搞乱了我的头! 我有点需要这个为我正在工作。 并且该算法不适用于swift和iOS以及它在java和android上的工作。

    let bigSize:Int = 200000
    var bigArray = [Int](count:bigSize,repeatedValue:0)

    let smallSize:Int = 20
    var smallArray = [Int](count:smallSize,repeatedValue:0)

    for i in 0..<bigSize
    {
        bigArray[i] = i + 8 * i
    }
    for i in 0..<smallSize
    {
        smallArray[i] = i + 9 * i
    }
    let indexBig = Int(arc4random_uniform(UInt32(bigSize)) % UInt32(bigSize))
    let indexSmall = Int(arc4random_uniform(UInt32(smallSize)) % UInt32(smallSize))

    var a = NSDate.timeIntervalSinceReferenceDate()
    print(bigArray[indexBig])
    var b = NSDate.timeIntervalSinceReferenceDate()
    print(b-a) prints 0.000888049602508545
    a = NSDate.timeIntervalSinceReferenceDate()
    print(smallArray[indexSmall])
    b = NSDate.timeIntervalSinceReferenceDate()
    print(b-a) prints 6.90221786499023e-05

java:(在java和它的pc上访问一个元素是如此之快,所以我访问更多的元素,但是两个数组的数量相同)

    int bigSize = 200000;
    int[] bigArray = new int[bigSize];
    Random rand = new Random();
    int smallSize = 20;
    int[] smallArray = new int[smallSize];
    for(int i = 0;i < bigSize;i++)
        bigArray[i] = i + i * 8;
    for(int i = 0;i < smallSize;i++)
        smallArray[i] = i + i * 8;
    int smallIndex = rand.nextInt(smallSize);
    int bigIndex = rand.nextInt(bigSize);
    int sum = 0;
    long a = System.currentTimeMillis();
    for(int i = 0;i < 10000;i++)
    {
        sum += bigArray[rand.nextInt(bigSize)];
    }
    System.out.println(sum);
    long b = System.currentTimeMillis();
    System.out.println(b-a); //prints 2
    a = System.currentTimeMillis();
    sum = 0;
    for(int i = 0; i < 10000;i++)
    {
        sum += smallArray[rand.nextInt(smallSize)];
    }
    System.out.println(sum);       
    b = System.currentTimeMillis();
    System.out.println(b - a); //prints 1

如果你改变两次测试的顺序,你会发现性能翻转了。 简而言之,无论是小阵列还是大阵列,第一次测试的运行速度都比第二次更慢。 这是print动态的结果。 如果你做了print在执行测试之前,从第一个产生的延迟print被消除。

更好的方法来测试这将是创建一个单元测试,其中(a)多次重复下标操作符; 和(b)使用measureBlock重复测试几次来检查标准偏差等。

当我这样做时,我发现访问时间是无法区分的,与O(1)一致。 这是我的单元测试:

let bigSize: Int = 200_000
let smallSize: Int = 20

func testBigArrayPerformance() {
    let size = bigSize

    let array = Array(0 ..< size).map { $0 + 8 * $0 }

    var value = 0

    measureBlock {
        let baseIndex = Int(arc4random_uniform(UInt32(size)))
        for index in 0 ..< 1_000_000 {
            value += array[(baseIndex + index) % size]
        }
    }

    print(value)
    print(array.count)
}

func testSmallArrayPerformance() {
    let size = smallSize

    let array = Array(0 ..< size).map { $0 + 8 * $0 }

    var value = 0

    measureBlock {
        let baseIndex = Int(arc4random_uniform(UInt32(size)))
        for index in 0 ..< 1_000_000 {
            value += array[(baseIndex + index) % size]
        }
    }

    print(value)
    print(array.count)
}

无可否认,我添加了一些数学运算来改变索引(我的意图是确保编译器没有做一些彻底的优化,去除了我重复下标操作的尝试),并且数学运算的开销会稀释下标操作员表现差异。 但是,即使我简化了指数算子,两次演绎之间的表现也是难以区分的。

链接地址: http://www.djcxy.com/p/35723.html

上一篇: Swift Array Performance Issue?

下一篇: UIBlurEffect in a custom modal presentation