Почему мой большой цикл for прошел от доли секунды до почти 8 секунд после обновления до Xcode 11 и IOS13? - PullRequest
0 голосов
/ 10 октября 2019

Я использую цикл for для перебора пикселей на изображении с камеры, чтобы определить процентное соотношение определенного цвета (зеленого). Изображение с камеры составляет 12 мегапикселей. Раньше скорость составляла всего лишь долю секунды, и теперь она занимает около 8 секунд на всех iPhone, которые я тестировал после обновления до Xcode 11.

func scanImageForPixels(_ image: CGImage) -> Float {
        // Create the context where we'll draw the image.
        let context = getContext(for: image)

        // Specify the area in the context to draw in. It should be the same size as the image.
        let imageWidth = image.width
        let imageHeight = image.height
        let imageRect = CGRect(x: 0, y: 0, width: CGFloat(imageWidth), height: CGFloat(imageHeight))

        // Draw the image so the context will contain the raw image data.
        context.draw(image, in: imageRect)

        // Get a pointer to the raw image data.
        let RGBAPointer = context.data!.assumingMemoryBound(to: UInt8.self)

        // Set up the numbers used to calculate "% Green"
        let totalPixels = imageWidth * imageHeight
        var greenPixels = 0

        // A 32-bit image will have 4 bytes per pixel: 1 byte for each component (RGBA). For example: 32bits / 8bits = 4bytes per pixel
        let bytesPerPixel = image.bitsPerPixel / image.bitsPerComponent

        let minRed: Int16   = 10
        let minBlue: Int16  = 10

        let start = Date()
        for pixelIndex in 0..<totalPixels {
            // move through the memory 4 bytes at a time
            let offset = pixelIndex * bytesPerPixel

            // change these from UInt8 to Int16 so we can do saturation/value calculations later (multiplying by 100 will make values greater than 255)
            // also make them signed, so we don't have to worry about negative numbers causing errors
            let red   = Int16(RGBAPointer[offset])
            let green = Int16(RGBAPointer[offset+1])
            let blue  = Int16(RGBAPointer[offset+2])
            //let alpha = Int16(RGBAPointer[offset+3]) // not used

            if (green - minRed) >= red && (green - minBlue) >= blue {
                greenPixels += 1
            }
        }
        let elapsed = NSDate().timeIntervalSince(start)
        print(elapsed)

        return Float(100 * Double(greenPixels) / Double(totalPixels))
    }

Прямо сейчас цикл for завершается за 7.063616037368774 секунды. ,Я ожидал, что это будет в 10 раз быстрее в зависимости от того, когда я использовал тот же код в предыдущих версиях Xcode.

...