performance - 在处理数字时,性能非常慢?

  显示原文与译文双语对照的内容
61 5

当我正在使用 Swift 教程时,我开始编写一个定制 isPrime 方法来检查给定的Int 是否是最佳的。

写完它之后我发现它工作正常,但是在某些情况下执行 isPrime 有点慢,相当大的数字( 比 Int.max 低得多) 。

所以我在objc中编写了相同的代码,并且代码执行得非常快。

下面是 Swift 代码:

class Swift {
 class func isPrime(n:Int) -> Bool {
 let sqr : Int = Int(sqrt(Double(n))) + 1
 for i in 2...sqr {
 if n % i == 0 {
 return false
 }
 }
 return true;
 }
 class func primesInRange(start:Int, end:Int) -> Int[] {
 var primes:Int[] = Int[]()
 for n in start...end {
 if self.isPrime(n) {
 primes.append(n)
 }
 }
 return primes;
 }
}

和objc代码:

@implementation Utils
+ (BOOL)isPrime:(NSUInteger)n {
 NSInteger sqr = (NSUInteger)(sqrt(n))+1;
 for (NSUInteger i = 2; i <sqr; ++i) {
 if (n % i == 0) {
 return false;
 }
 }
 return YES;
}
+ (NSArray*)primesInRange:(NSUInteger)start end:(NSUInteger)end {
 NSMutableArray* primes = [NSMutableArray array];
 for (NSUInteger i = start; i <= end; ++i) {
 if ([self isPrime:i])
 [primes addObject:@(i)];
 }
 return primes.copy;
}
@end

main.swift 中:

let startDateSwift = NSDate.date()
let swiftPrimes = Swift.primesInRange(1_040_101_022_000, end: 1_040_101_022_200)
let elapsedSwift = NSDate.date().timeIntervalSinceDate(startDateSwift)*1000
let startDateObjc = NSDate.date()
let objcPrimes = Utils.primesInRange(1_040_101_022_000, end: 1_040_101_022_200)
let elapsedObjc = NSDate.date().timeIntervalSinceDate(startDateObjc)*1000
println("(swiftPrimes) took: (elapsedSwift)ms");
println("(objcPrimes) took: (elapsedObjc)ms");

这产生了:

[1040101022027, 1040101022039, 1040101022057, 1040101022099, 1040101022153] took: 3953.82004976273ms
[1040101022027, 1040101022039, 1040101022057, 1040101022099, 1040101022153] took: 66.4250254631042ms

我知道我可以以在这里使用 extension 来检查一个数是否是最好的,但是我希望这两个代码是非常相似。

谁能告诉我为什么这个 Swift 代码要慢得多?66x 因子相当可怕,只有当我增加范围时才会变得更糟糕。

时间:原作者:0个回答

106 2

下面是编译器生成( 你可以在生成设置中找到它们)的Swift代码的优化级别:

[-Onone] no optimizations, the default for debug.
[-O] perform optimizations, the default for release.
[-Ofast] perform optimizations and disable runtime overflow checks and runtime type checks.

使用你的代码,我得到了不同级别的优化:

[-Onone]

Swift: 6110.98903417587ms
Objc: 134.006023406982ms

[-O]

Swift: 89.8249745368958ms
Objc: 85.5680108070374ms

[-Ofast]

Swift: 77.1470069885254ms
Objc: 76.3399600982666ms

请记住,-Ofast有风险。比如 将默认忽略整数和 array 溢出,产生无意义的结果,因这里如果你选择使用它,则不可以能。

原作者:
...