Section 11/151 menit

11. Performa dan Optimasi

11. Performa dan Optimasi

Profiling AI Performance

swift
import os

// Gunakan os_signpost untuk profiling AI requests

let log = OSLog(subsystem: "com.company.app", category: "AIPerformance")

class ProfiledVisionAnalyzer {

    func profiledOCR(image: UIImage) async -> [String] {
        let signpostID = OSSignpostID(log: log)

        os_signpost(.begin, log: log, name: "OCR Request", signpostID: signpostID,
                    "Image size: %{public}@", "\(image.size)")

        defer {
            os_signpost(.end, log: log, name: "OCR Request", signpostID: signpostID)
        }

        guard let cgImage = image.cgImage else { return [] }
        let request = VNRecognizeTextRequest()
        try? VNImageRequestHandler(cgImage: cgImage).perform([request])
        return request.results?.compactMap { $0.topCandidates(1).first?.string } ?? []
    }
}

Batching dan Async Processing

swift
// Proses multiple gambar secara concurrent dengan throttling

class BatchImageAnalyzer {

    private let maxConcurrency = 4  // sesuaikan dengan jumlah core

    func analyzeImages(_ images: [UIImage]) async -> [AnalysisResult] {
        await withTaskGroup(of: AnalysisResult?.self) { group in
            // Batasi concurrent task
            let semaphore = AsyncSemaphore(limit: maxConcurrency)

            for (index, image) in images.enumerated() {
                group.addTask {
                    await semaphore.wait()
                    defer { semaphore.signal() }

                    let text = await self.extractText(from: image)
                    return AnalysisResult(index: index, text: text)
                }
            }

            var results: [AnalysisResult] = []
            for await result in group {
                if let result { results.append(result) }
            }
            return results.sorted { $0.index < $1.index }
        }
    }

    private func extractText(from image: UIImage) async -> String {
        guard let cgImage = image.cgImage else { return "" }
        let request = VNRecognizeTextRequest()
        try? VNImageRequestHandler(cgImage: cgImage).perform([request])
        return request.results?.compactMap { $0.topCandidates(1).first?.string }.joined(separator: " ") ?? ""
    }
}

struct AnalysisResult {
    let index: Int
    let text: String
}

// Simple AsyncSemaphore implementation
actor AsyncSemaphore {
    private var count: Int
    private var waiters: [CheckedContinuation<Void, Never>] = []

    init(limit: Int) { count = limit }

    func wait() async {
        if count > 0 { count -= 1; return }
        await withCheckedContinuation { waiters.append($0) }
    }

    func signal() {
        if waiters.isEmpty { count += 1 }
        else { waiters.removeFirst().resume() }
    }
}