Мне нужно сделать быструю функцию для определения размера областей определенного цвета. Функция, которую я написал, но не могу получить скорость обработки, которую я имею для той же функции в Objective C.
После нескольких дней оптимизации на iPhone 7Plus и изображении 2048x2048 поиск 256 зон занимает 1,04 с на ObjectiveC и 2,5 с на Swift.
Что я пропустил и где можно оптимизировать код Swift?
@IBAction func allZonesOpt(_ sender: Any) {
let startDate = Date()
let image : UIImage = UIImage(named:"idx.png")!
let cgImage : CGImage = image.cgImage!
guard let pixelData = CGDataProvider(data: (cgImage.dataProvider?.data)!)?.data else {
return
}
let data = CFDataGetBytePtr(pixelData)!
let numberOfComponents:Int = 4
let imageWidth = Int(image.size.width)
let imageHeight = Int(image.size.height)
let bytesPerRow = imageWidth * numberOfComponents
let rangeOne = 0..<Int(image.size.height)
let rangeTwo = 0..<Int(image.size.width)
var arrayWithZones = [(Int, Int)]()
for colorRed:UInt8 in 0...255 {
// autoreleasepool {
let colorR = colorRed
let colorG = 0
let colorB = 0
var minx:Int = imageWidth
var miny:Int = imageHeight
var maxx:Int = 0
var maxy:Int = 0
let startDateFor = Date()
for y in rangeOne {
for x in rangeTwo {
let pixelData = (bytesPerRow * y) + x * numberOfComponents
if data[pixelData] == colorR && data[pixelData + 1] == colorG && data[pixelData+2] == colorB{
if minx > x{
minx = x
}
if miny > y{
miny = y
}
if maxx < x{
maxx = x
}
if maxy < y{
maxy = y
}
}
}
}
let methodFinishFor = Date()
let timeIntervalFor = methodFinishFor.timeIntervalSince(startDateFor)
print(" time execution = \(timeIntervalFor)")
arrayWithZones.append((maxx - minx, maxy - miny))
// let finalSize = CGSize(width: maxx - minx, height: maxy - miny)
// print("final = \(finalSize)")
// }
}
let methodFinish = Date()
let timeInterval = methodFinish.timeIntervalSince(startDate)
resultLabel.text = " time execution = \(timeInterval)"
print(" time execution = \(timeInterval)")
print("atFinal = \(arrayWithZones)");
}
Objective-C:
- (IBAction)allZonesAsSwift:(id)sender {
NSDate *methodStart = [NSDate date];
UIImage *image = [UIImage imageNamed:@"idx.png"];
//static rawData
CGImageRef imageRef = [image CGImage];
unsigned int width = (unsigned int)CGImageGetWidth(imageRef);
unsigned int height = (unsigned int)CGImageGetHeight(imageRef);
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * width;
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
const unsigned char * rawData = CFDataGetBytePtr(data);
unsigned int minx = image.size.width;
unsigned int miny = image.size.height;
unsigned int maxx = 0;
unsigned int maxy = 0;
unsigned char colorR = 0;
unsigned char colorG = 0;
unsigned char colorB = 0;
NSMutableArray *arrayWithZones = [NSMutableArray<NSValue*> new];
for (int colorRed = 0; colorRed < 256; colorRed ++) {
colorR = (unsigned char)colorRed;
minx = (unsigned int)image.size.width;
miny = (unsigned int)image.size.height;
maxx = 0;
maxy = 0;
NSDate *methodStartFor = [NSDate date];
for (unsigned int y = height - 1; y; y--) {
for (unsigned int x = width - 1; x; x--) {
unsigned int byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
if (rawData[byteIndex] == colorR && rawData[byteIndex + 1] == colorG && rawData[byteIndex + 2] == colorB) {
minx = x < minx ? x : minx;
maxx = x > maxx ? x : maxx;
miny = y < miny ? y : miny;
maxy = y > maxy ? y : maxy;
}
}
}
NSDate *methodFinishFor = [NSDate date];
NSTimeInterval executionTimeFor = [methodFinishFor timeIntervalSinceDate:methodStartFor];
NSLog(@"executionTime Zone = %f", executionTimeFor);
CGSize final = CGSizeMake(maxx - minx, maxy - miny);
[arrayWithZones addObject:[NSValue valueWithCGSize:final]];
}
free(rawData);
NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"color picker = %f", executionTime);
_resultLabel.text = [NSString stringWithFormat:@"color picker = %f", executionTime];
NSLog(@"final = %@", arrayWithZones);
}