swift中的二维数组迭代速度(Beta 4)

时间:2021-04-28 21:35:00

I've been battling with speed issues in Swift, mainly with arrays. Currently running with latest 'beta 4' release. I've broken the code out into playground to try and show the issues

我一直在用Swift处理速度问题,主要是用数组。目前正在运行最新的beta 4版本。我已经把代码分解到操场上,试着展示这些问题

I setup an 2D array, the iterate over it, set each element.

我设置了一个2D数组,遍历它,设置每个元素。

import UIKit

func getCurrentMillitime() -> NSTimeInterval {
    let date: NSDate = NSDate()
    return date.timeIntervalSince1970*1000;
}

let startTime = getCurrentMillitime()

let X = 40
let Y = 50
var distanceGrid = [[CGFloat]](count: X, repeatedValue:[CGFloat](count: Y,repeatedValue:CGFloat(0.0)))
for xi in 0..<X {
    for yi in 0..<Y {
        distanceGrid[xi][yi] = 1.1
       //println("x:\(xi) y:\(yi) d:\(distanceGrid[xi][yi])")
    }
}

let endTime = getCurrentMillitime()
let computationTime = endTime - startTime
println("Time to compute \(computationTime) ms")

Run the above code and you'll get :

运行上述代码,您将得到:

Time to compute 2370.203125 ms

Which sure can't be right !.. Am I being a numpty ?

这肯定是不对的!我是个笨蛋吗?

4 个解决方案

#1


0  

It's obvious that the Swift beta is struggling with arrays. Even with a one-dimensional array, compared to objective-c the difference is huge.

显然,Swift beta版正在与数组做斗争。即使是使用一维数组,与objective-c相比,差异也是巨大的。

I've mixed a objC class into a swift program and had both languages create and alter an array of 1,000,000 elements. This is what I got on some MacBook:

我将objC类混合到swift程序中,并让两种语言创建和修改一个包含1,000,000个元素的数组。这是我在MacBook上买的:

Elapsed time by Swift method: 2.7078 sec Elapsed time by objective-c method: 0.033815 seconds

Swift法运行时间:2.7078秒,objective-c法运行时间:0.033815秒

Code: ( var nrOfElements = 1000000 )

代码:(var nrOfElements = 1000000)

  // Swift
    let startTime = NSDate();
    var stringList = Array<String>(count: nrOfElements, repeatedValue:String())
    for i in 0..<nrOfElements {
      stringList[i] = "Some string";
    }
    let endTime = NSDate();
    println("Elapsed time by Swift method: " +
      NSString(format:"%.4f", endTime.timeIntervalSinceDate(startTime)) + " sec");

   // Objective-c
      NSDate *startTime = [NSDate date];
      NSMutableArray *stringList = [NSMutableArray arrayWithCapacity:10];
      for (int i = 0; i < nrOfElements; i++) {
        [stringList addObject:@"Some string"];
      }
      NSDate *endTime = [NSDate date];
      printf("%s\n", [[NSString stringWithFormat:@"Elapsed time by objective-c method: %f seconds", [endTime timeIntervalSinceDate:startTime]] UTF8String]);
  • I found no difference between Beta-3 and Beta-4, so improving array-handling isn't high on the priority list.
  • 我发现-3和-4之间没有区别,所以改进阵列处理并不是首要任务。
  • Processing increasingly larger arrays, give proportional higher process times.
  • 处理越来越大的阵列,给予比例较高的处理时间。
  • Handling multi-dimensional arrays is even more costly when increasing the number of higher dimension elements
  • 当增加高维元素的数量时,处理多维数组的成本甚至更高
  • Pre-creation of the array in Swift is indeed faster than 'append'
  • 在Swift中预先创建数组的速度确实比“追加”快

Let's hope that things adequately will be repaired in the final version.

让我们希望在最终版本中能够充分修复这些问题。

#2


2  

Two things to consider about Swift performance:

关于Swift性能,有两点需要考虑:

  • It's very much up in the air during the beta.

    在beta测试期间,它在很大程度上是悬而未决的。

  • Many of Swift's performance tricks depend on the optimizer. Especially when generics are involved (every array is a generic Array<T>), Swift uses a more expressive / debugger-friendly implementation at -O0, but optimizes it away to a higher-performance implementation at -O or -Ofast. (Note that -Ofast also takes away bounds checks and other safety features, so it's not a great idea for production builds.)

    Swift的许多性能技巧都依赖于优化器。特别是当涉及到泛型时(每个数组都是泛型数组 ), Swift在-O0处使用了一种更易于表达/调试器的实现,但将其优化为-O或-Ofast处的高性能实现。(注意-Ofast还去掉了边界检查和其他安全特性,因此这对生产构建不是一个好主意。)

Also, note your current example is measuring both the time to create a 2D array with init(count:repeatedValue: and the time to iterate it. If you're out to measure only the latter, you should set your startTime after creating the arrays.

另外,请注意,您当前的示例度量了使用init创建2D数组的时间(count:repeatedValue:以及迭代它的时间。如果只测量后者,应该在创建数组之后设置开始时间。

#3


0  

In the language guide under "subscripts", you'll find a 2D (struct) implementation of a 2D array. But it is rather slow in assigning values if you go above a 1000 elements.

在“下标”下的语言指南中,您将找到二维数组的2D (struct)实现。但是如果超过1000个元素,分配值就会比较慢。

Creating a local 2D array and setting it into the struct for easy acces is much faster.

创建一个本地2D数组并将其设置为易于操作的结构会快得多。

It's also faster to create an array with repeated values and overwrite them than to append values to an array.

创建具有重复值的数组并覆盖它们也比向数组追加值要快。

For about 100k values it takes ~9seconds with the struct, 1.5 seconds with the append and 0.6 seconds with overwriting repeated values.

对于大约100k的值,使用struct需要9秒,使用附加项需要1.5秒,覆盖重复值需要0.6秒。

I kinda like the struct idea, but it is so slow. I sure hope it's a beta issue.

我有点喜欢这个结构的想法,但是它太慢了。我真希望这是测试版的问题。

#4


0  

I agree with you that even a beta version cannot behave like software of the eighties on hardware of the seventies. So I did some more digging into the Swift array-handling capabilities and I stumbled upon astonishing results. We learned already that the Swift array performance is poor when compared to objective-c or other languages as c++, c#, java, etc.

我同意你的观点,即使是测试版也不能像八十年代的硬件那样运行。因此,我进一步深入研究了快速阵列处理能力,偶然发现了惊人的结果。我们已经了解到,与objective-c或其他语言如c++、c#、java等相比,Swift数组的性能很差。

In my previous tests I measured the time to create and fill a local scope array of one million elements. As we saw, objective-c did this about 80 times faster. Worse it gets when we compare arrays declared in global class scope. Then objC appears to be about 500 times faster!

在我之前的测试中,我测量了创建和填充一个包含100万个元素的局部范围数组的时间。就像我们看到的,objective-c快了80倍。更糟糕的是,当我们比较全局类作用域中声明的数组时。然后objC似乎快500倍!

But hey, when we finally have filled up this global declared array with useful data, we can smoothly work with it right? Wrong!

但是,嘿,当我们最终用有用的数据填充这个全局声明数组时,我们可以很顺利地处理它,对吗?错了!

I’ve printed 10 elements of the large array and the nightmare deepened. The 10 elements of a local scope array took 0,0004 seconds, as may be expected. But printing the same elements of our global declared array took… 1 minute and 11 seconds. This seems too bad to be true and I’m sure the Swift developers are on it as we speak.

我打印了10个大数组元素,噩梦加深了。正如预期的那样,本地范围数组的10个元素花费了0,0004秒。但是打印我们全局声明数组的相同元素需要1分11秒。这似乎太糟糕了,我敢肯定,当我们说话的时候,迅速的开发人员也会这么做。

#1


0  

It's obvious that the Swift beta is struggling with arrays. Even with a one-dimensional array, compared to objective-c the difference is huge.

显然,Swift beta版正在与数组做斗争。即使是使用一维数组,与objective-c相比,差异也是巨大的。

I've mixed a objC class into a swift program and had both languages create and alter an array of 1,000,000 elements. This is what I got on some MacBook:

我将objC类混合到swift程序中,并让两种语言创建和修改一个包含1,000,000个元素的数组。这是我在MacBook上买的:

Elapsed time by Swift method: 2.7078 sec Elapsed time by objective-c method: 0.033815 seconds

Swift法运行时间:2.7078秒,objective-c法运行时间:0.033815秒

Code: ( var nrOfElements = 1000000 )

代码:(var nrOfElements = 1000000)

  // Swift
    let startTime = NSDate();
    var stringList = Array<String>(count: nrOfElements, repeatedValue:String())
    for i in 0..<nrOfElements {
      stringList[i] = "Some string";
    }
    let endTime = NSDate();
    println("Elapsed time by Swift method: " +
      NSString(format:"%.4f", endTime.timeIntervalSinceDate(startTime)) + " sec");

   // Objective-c
      NSDate *startTime = [NSDate date];
      NSMutableArray *stringList = [NSMutableArray arrayWithCapacity:10];
      for (int i = 0; i < nrOfElements; i++) {
        [stringList addObject:@"Some string"];
      }
      NSDate *endTime = [NSDate date];
      printf("%s\n", [[NSString stringWithFormat:@"Elapsed time by objective-c method: %f seconds", [endTime timeIntervalSinceDate:startTime]] UTF8String]);
  • I found no difference between Beta-3 and Beta-4, so improving array-handling isn't high on the priority list.
  • 我发现-3和-4之间没有区别,所以改进阵列处理并不是首要任务。
  • Processing increasingly larger arrays, give proportional higher process times.
  • 处理越来越大的阵列,给予比例较高的处理时间。
  • Handling multi-dimensional arrays is even more costly when increasing the number of higher dimension elements
  • 当增加高维元素的数量时,处理多维数组的成本甚至更高
  • Pre-creation of the array in Swift is indeed faster than 'append'
  • 在Swift中预先创建数组的速度确实比“追加”快

Let's hope that things adequately will be repaired in the final version.

让我们希望在最终版本中能够充分修复这些问题。

#2


2  

Two things to consider about Swift performance:

关于Swift性能,有两点需要考虑:

  • It's very much up in the air during the beta.

    在beta测试期间,它在很大程度上是悬而未决的。

  • Many of Swift's performance tricks depend on the optimizer. Especially when generics are involved (every array is a generic Array<T>), Swift uses a more expressive / debugger-friendly implementation at -O0, but optimizes it away to a higher-performance implementation at -O or -Ofast. (Note that -Ofast also takes away bounds checks and other safety features, so it's not a great idea for production builds.)

    Swift的许多性能技巧都依赖于优化器。特别是当涉及到泛型时(每个数组都是泛型数组 ), Swift在-O0处使用了一种更易于表达/调试器的实现,但将其优化为-O或-Ofast处的高性能实现。(注意-Ofast还去掉了边界检查和其他安全特性,因此这对生产构建不是一个好主意。)

Also, note your current example is measuring both the time to create a 2D array with init(count:repeatedValue: and the time to iterate it. If you're out to measure only the latter, you should set your startTime after creating the arrays.

另外,请注意,您当前的示例度量了使用init创建2D数组的时间(count:repeatedValue:以及迭代它的时间。如果只测量后者,应该在创建数组之后设置开始时间。

#3


0  

In the language guide under "subscripts", you'll find a 2D (struct) implementation of a 2D array. But it is rather slow in assigning values if you go above a 1000 elements.

在“下标”下的语言指南中,您将找到二维数组的2D (struct)实现。但是如果超过1000个元素,分配值就会比较慢。

Creating a local 2D array and setting it into the struct for easy acces is much faster.

创建一个本地2D数组并将其设置为易于操作的结构会快得多。

It's also faster to create an array with repeated values and overwrite them than to append values to an array.

创建具有重复值的数组并覆盖它们也比向数组追加值要快。

For about 100k values it takes ~9seconds with the struct, 1.5 seconds with the append and 0.6 seconds with overwriting repeated values.

对于大约100k的值,使用struct需要9秒,使用附加项需要1.5秒,覆盖重复值需要0.6秒。

I kinda like the struct idea, but it is so slow. I sure hope it's a beta issue.

我有点喜欢这个结构的想法,但是它太慢了。我真希望这是测试版的问题。

#4


0  

I agree with you that even a beta version cannot behave like software of the eighties on hardware of the seventies. So I did some more digging into the Swift array-handling capabilities and I stumbled upon astonishing results. We learned already that the Swift array performance is poor when compared to objective-c or other languages as c++, c#, java, etc.

我同意你的观点,即使是测试版也不能像八十年代的硬件那样运行。因此,我进一步深入研究了快速阵列处理能力,偶然发现了惊人的结果。我们已经了解到,与objective-c或其他语言如c++、c#、java等相比,Swift数组的性能很差。

In my previous tests I measured the time to create and fill a local scope array of one million elements. As we saw, objective-c did this about 80 times faster. Worse it gets when we compare arrays declared in global class scope. Then objC appears to be about 500 times faster!

在我之前的测试中,我测量了创建和填充一个包含100万个元素的局部范围数组的时间。就像我们看到的,objective-c快了80倍。更糟糕的是,当我们比较全局类作用域中声明的数组时。然后objC似乎快500倍!

But hey, when we finally have filled up this global declared array with useful data, we can smoothly work with it right? Wrong!

但是,嘿,当我们最终用有用的数据填充这个全局声明数组时,我们可以很顺利地处理它,对吗?错了!

I’ve printed 10 elements of the large array and the nightmare deepened. The 10 elements of a local scope array took 0,0004 seconds, as may be expected. But printing the same elements of our global declared array took… 1 minute and 11 seconds. This seems too bad to be true and I’m sure the Swift developers are on it as we speak.

我打印了10个大数组元素,噩梦加深了。正如预期的那样,本地范围数组的10个元素花费了0,0004秒。但是打印我们全局声明数组的相同元素需要1分11秒。这似乎太糟糕了,我敢肯定,当我们说话的时候,迅速的开发人员也会这么做。