Производительность Swift vs Objective-C
Я просто сравниваю производительность Swift и Objective-C. Для этого я использую NSDate для измерения времени, но я получаю большую разницу между Swift и Objective-C. Я просто запускал пустой цикл for
100 000 раз. Вот мой код,
В Objective-C,
NSDate * start = [NSDate date];
for (int i=0; i<=100000; i++) {
}
NSDate * end = [NSDate date];
double timeTaken = [end timeIntervalSinceDate:start] * 1000;
timeTaken составляет 0,24 миллисекунды
В Swift,
var start = NSDate()
for i in 0...100000
{
}
var end = NSDate()
var timeTaken = end.timeIntervalSinceDate(start) * 1000
timeTaken
составляет 74 миллисекунды в Swift, что является большой разницей по сравнению с Objective-C.
Я делаю что-то не так в этом измерении?
Ответы
Ответ 1
Я не думаю, что это очень справедливое сравнение. Вы только просите Objective-C выполнить цикл, но вы попросите Swift создать массивный диапазон (в частности Range<Int>
), а затем повторите его. На моем компьютере требуется примерно 0,53 секунды для перехода по диапазону до миллиона, но всего около 0,012 секунды для выполнения цикла for
до миллиона, что сравнивается с 0,002 секундами, которое требуется программе в Objective-C.
Мои программы (оба проекта устанавливаются как инструменты командной строки)
import Foundation
let start = CFAbsoluteTimeGetCurrent()
//for i in 0...1000000 {
//
//}
for var i = 0; i <= 1000000; ++i {
}
let timeTaken = CFAbsoluteTimeGetCurrent() - start
println(timeTaken)
И Objective-C
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
double start = CFAbsoluteTimeGetCurrent();
for (int i = 0; i <= 1000000; i++) {
}
double timeTaken = CFAbsoluteTimeGetCurrent() - start;
NSLog(@"%f",timeTaken);
}
return 0;
}
Удаление пула авторешетки даже сбрасывает еще одну тысячную доли секунды. Но, в целом, разница не так велика, как кажется.
Ответ 2
То, что вы делаете, - это чистая чепуха. Не имеет значения, какова производительность этого цикла, потому что это не происходит в реальном коде. Существенное различие заключается в том, что в Swift цикл будет выполнять проверки переполнения на каждом шаге, которые являются обязательным побочным эффектом из-за определения языка. В Objective-C это не так.
По крайней мере, вам нужно сделать код, который действительно имеет смысл.
Я провел некоторые реальные тесты, и результаты были следующими: 1. Скорость Swift и простая C для операций низкого уровня сопоставимы. 2. Когда при переполнении произойдет, Swift убьет программу, чтобы вы могли заметить переполнение, а C и Objective-C будут молча давать вам бессмысленные результаты. Попробуйте следующее:
var i: Int = 0
var s: Double = 0.0
for (i in 1 .. 10_000_000_000) { s += Double (i * i) }
Swift выйдет из строя. (Любой, кто считает, что плохое не имеет понятия о программировании). То же самое в Objective-C приведет к бессмысленному результату. Замените петлю на
for (i in 1 .. 10_000_000_000) { s += Double (i) * Double (i) }
и оба работают со сравнимой скоростью.
Ответ 3
По умолчанию уровень оптимизации компилятора установлен в None [-Onone]
в режиме отладки...
Изменение этого параметра на Fastest [-O]
(например, release) дает следующие результаты:
![Enter image description here]()
Ответ 4
Я провел несколько тестов с функцией сортировки, которая использовала собственный массив Swift и строку Swift по сравнению с переменным массивом Objective C и NSString.
Функция упорядочивала 1000 строк, и она выполняла сравнение строк milion и перетасовывала массив.
Результаты были следующими:
-
Цель C (используя примитивные целые числа и логические значения): 0,32 секунды
-
Цель C (с использованием NSNumber для целых чисел и логических элементов): 0.45 секунд
-
Swift в режиме отладки: 13 секунд:)
-
Swift с уровнем оптимизации (самый быстрый [-O]): 1,32 секунды
-
Swift с уровнем оптимизации (Fastest, Unchecked [-Ofast]): 0.67 секунд
Кажется, что в быстром режиме Swift довольно близок к Objective C, но он все еще не быстрее, чем Apple (ed).
Это код сортировки, который я использовал:
Swift:
var strFile = String.stringWithContentsOfFile("1000strings.txt", encoding: NSUTF8StringEncoding, error: nil)
var strings:String[] = strFile!.componentsSeparatedByString("\n")
var startDate = NSDate()
var shouldLoopAgain = true
var numberOfLoops = 0
while shouldLoopAgain {
shouldLoopAgain = false
++numberOfLoops
for var i = 0; i < strings.count-1; ++i {
if (strings[i] > strings[i+1]) {
let temp = strings[i]
strings[i] = strings[i+1]
strings[i+1] = temp;
if !shouldLoopAgain {
shouldLoopAgain = true
}
}
}
}
var time = NSDate().timeIntervalSinceDate(startDate)
Цель C с примитивными булевыми и целыми числами
NSMutableArray *strings = [NSMutableArray arrayWithArray:[strFile componentsSeparatedByString:@"\n"]];
NSDate *startDate = [NSDate date];
BOOL shouldLoopAgain = YES;
int numberOfLoops = 0;
while (shouldLoopAgain) {
shouldLoopAgain = NO;
++numberOfLoops;
for (int i = 0; i < strings.count-1; ++i) {
if ([strings[i] compare:strings[i+1]] == NSOrderedDescending) {
NSString *temp = strings[i];
strings[i] = strings[i+1];
strings[i+1] = temp;
if (!shouldLoopAgain) {
shouldLoopAgain = YES;
}
}
}
}
NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:startDate];
Цель C с NSNumber для логических и целых чисел
NSDate *startDate = [NSDate date];
NSNumber *shouldLoopAgain = @YES;
NSNumber *numberOfLoops = @(0);
while ([shouldLoopAgain boolValue]) {
shouldLoopAgain = @NO;
numberOfLoops = @([numberOfLoops intValue]+1);
for (NSNumber *i = 0; [i intValue] < strings.count-1; i = @([i intValue]+1)) {
if ([strings[[i intValue]] compare:strings[[i intValue]+1]] == NSOrderedDescending) {
NSString *temp = strings[[i intValue]];
strings[[i intValue]] = strings[[i intValue]+1];
strings[[i intValue]+1] = temp;
if (![shouldLoopAgain boolValue]) {
shouldLoopAgain = @YES;
}
}
}
}
NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:startDate];
Ответ 5
Попробуйте выполнить компиляцию с включенными оптимизациями. Если это не изменит ситуацию, сообщите об ошибке с Apple. Swift все еще находится в состоянии бета-тестирования, поэтому могут быть грубые пятна.
Ответ 6
Я не думаю, что с сегодняшнего дня вы можете запускать эти тесты и с какой-либо определенностью определить, будет ли Swift 1.0 быстрее или медленнее, чем Objective-C. Весь язык Swift все еще находится в стадии разработки, синтаксис и способ реализации аспектов языка. Это видно из изменений в языке между Xcode 6 Betas 2 и 3, и если вы посмотрите на Apple Dev Forums, вы можете увидеть парня Apple, который работает на этом языке, четко заявив, что материал не является полным или оптимизированным, и что это будет не до версии Swift 1.0, которая должна произойти наряду с публичным выпуском Xcode 6.
Итак, я не говорю, что сейчас нет смысла делать эти тесты, но до тех пор, пока Swift 1.0 не будет завершен, мы не можем сказать ничего убедительного в отношении окончательной производительности.
Ответ 7
Посмотрите https://softwareengineering.stackexchange.com/info/242816/how-can-swift-be-so-much-faster-than-objective-c-in-these-comparisons и http://www.splasmata.com/?p=2798 учебник, возможно быть может, вы получите ответ. Но главное, что язык Swift все еще находится в стадии бета-тестирования. А также яблоко делает/не может уверенно объявить, что Swift быстрее, чем objective-c во всех случаях. Apple сообщила нам, что средняя производительность. Мое мнение состоит в том, что если в некоторых случаях obj-c быстрее, чем быстрее, это не означает, что все более быстрые показатели производительности медленнее. Мы просто уделяем больше времени Apple для этого.