Prima di tutto, il tuo "modo nativo" non è equivalente a "Swifty way".
La versione di SwiftyJSON ha 45 subscript
accessi, ma la modalità nativa ha solo 23 subscript
accessi.
di fare "modo nativo" equivalente, dovrebbe essere qualcosa di simile:
let openDescription = attraction["OpeningHours"]!["OpeningHoursGenericExceptions"] as String
let monOpen = (attraction["OpeningHours"]!["Monday"]!!["From"] as String).componentsSeparatedByString(":")
let monClose = (attraction["OpeningHours"]!["Monday"]!!["To"] as String).componentsSeparatedByString(":")
let tueOpen = (attraction["OpeningHours"]!["Tuesday"]!!["From"] as String).componentsSeparatedByString(":")
let tueClose = (attraction["OpeningHours"]!["Tuesday"]!!["To"]! as String).componentsSeparatedByString(":")
// ...
o "via Swifty" dovrebbe essere come:
let openHours = json[0]["OpeningHours"]
var day:JSON
day = openHours["Monday"]
if let open = day["From"].string {
monOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
monClose = close.componentsSeparatedByString(":")
}
day = openHours["Tuesday"]
if let open = day["From"].string {
tueOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
tueClose = close.componentsSeparatedByString(":")
}
// ...
Comunque, sì, SwiftyJSON è lento. Facciamo misura:
import Foundation
import XCTest
let orgJson:AnyObject = [
[
"OpeningHours": [
"OpeningHoursGenericExceptions": "test",
"Monday": ["From":"1:2:3","To":"1:2:3"],
"Tuesday": ["From":"1:2:3","To":"1:2:3"],
"Wednesday": ["From":"1:2:3","To":"1:2:3"],
"Thursday": ["From":"1:2:3","To":"1:2:3"],
"Friday": ["From":"1:2:3","To":"1:2:3"],
"Saturday": ["From":"1:2:3","To":"1:2:3"],
"Sunday": ["From":"1:2:3","To":"1:2:3"],
]
]
]
let json = JSON(orgJson)
class JSONTestTests: XCTestCase {
func testNativeSubscript() {
measureBlock {() -> Void in
for _ in 0 ..< 400 {
autoreleasepool {
if let attraction = orgJson[0] as? NSDictionary {
let openDescription = attraction["OpeningHours"]!["OpeningHoursGenericExceptions"] as String
let monOpen = (attraction["OpeningHours"]!["Monday"]!!["From"] as String).componentsSeparatedByString(":")
let monClose = (attraction["OpeningHours"]!["Monday"]!!["To"] as String).componentsSeparatedByString(":")
let tueOpen = (attraction["OpeningHours"]!["Tuesday"]!!["From"] as String).componentsSeparatedByString(":")
let tueClose = (attraction["OpeningHours"]!["Tuesday"]!!["To"] as String).componentsSeparatedByString(":")
let wedOpen = (attraction["OpeningHours"]!["Wednesday"]!!["From"] as String).componentsSeparatedByString(":")
let wedClose = (attraction["OpeningHours"]!["Wednesday"]!!["To"] as String).componentsSeparatedByString(":")
let thuOpen = (attraction["OpeningHours"]!["Thursday"]!!["From"] as String).componentsSeparatedByString(":")
let thuClose = (attraction["OpeningHours"]!["Thursday"]!!["To"] as String).componentsSeparatedByString(":")
let friOpen = (attraction["OpeningHours"]!["Friday"]!!["From"] as String).componentsSeparatedByString(":")
let friClose = (attraction["OpeningHours"]!["Friday"]!!["To"] as String).componentsSeparatedByString(":")
let satOpen = (attraction["OpeningHours"]!["Saturday"]!!["From"] as String).componentsSeparatedByString(":")
let satClose = (attraction["OpeningHours"]!["Saturday"]!!["To"] as String).componentsSeparatedByString(":")
let sunOpen = (attraction["OpeningHours"]!["Sunday"]!!["From"] as String).componentsSeparatedByString(":")
let sunClose = (attraction["OpeningHours"]!["Sunday"]!!["To"] as String).componentsSeparatedByString(":")
XCTAssertEqual(monOpen, ["1","2","3"], "")
XCTAssertEqual(openDescription, "test")
}
}
}
}
}
func testJSONSubscript() {
measureBlock {() -> Void in
for _ in 0 ..< 400 {
autoreleasepool {
let attraction = json[0]
let openDescription:String = attraction["OpeningHours"]["OpeningHoursGenericExceptions"].string!
let monOpen:[String] = attraction["OpeningHours"]["Monday"]["From"].string!.componentsSeparatedByString(":")
let monClose:[String] = attraction["OpeningHours"]["Monday"]["To"].string!.componentsSeparatedByString(":")
let tueOpen:[String] = attraction["OpeningHours"]["Tuesday"]["From"].string!.componentsSeparatedByString(":")
let tueClose:[String] = attraction["OpeningHours"]["Tuesday"]["To"].string!.componentsSeparatedByString(":")
let wedOpen:[String] = attraction["OpeningHours"]["Wednesday"]["From"].string!.componentsSeparatedByString(":")
let wedClose:[String] = attraction["OpeningHours"]["Wednesday"]["To"].string!.componentsSeparatedByString(":")
let thuOpen:[String] = attraction["OpeningHours"]["Thursday"]["From"].string!.componentsSeparatedByString(":")
let thuClose:[String] = attraction["OpeningHours"]["Thursday"]["To"].string!.componentsSeparatedByString(":")
let friOpen:[String] = attraction["OpeningHours"]["Friday"]["From"].string!.componentsSeparatedByString(":")
let friClose:[String] = attraction["OpeningHours"]["Friday"]["To"].string!.componentsSeparatedByString(":")
let satOpen:[String] = attraction["OpeningHours"]["Saturday"]["From"].string!.componentsSeparatedByString(":")
let satClose:[String] = attraction["OpeningHours"]["Saturday"]["To"].string!.componentsSeparatedByString(":")
let sunOpen:[String] = attraction["OpeningHours"]["Sunday"]["From"].string!.componentsSeparatedByString(":")
let sunClose:[String] = attraction["OpeningHours"]["Sunday"]["To"].string!.componentsSeparatedByString(":")
XCTAssertEqual(monOpen, ["1","2","3"], "")
}
}
}
}
func testNativeBinding() {
measureBlock {() -> Void in
for _ in 0 ..< 400 {
autoreleasepool {
var monOpen:[String] = []
var monClose:[String] = []
var tueOpen:[String] = []
var tueClose:[String] = []
var wedOpen:[String] = []
var wedClose:[String] = []
var thuOpen:[String] = []
var thuClose:[String] = []
var friOpen:[String] = []
var friClose:[String] = []
var satOpen:[String] = []
var satClose:[String] = []
var sunOpen:[String] = []
var sunClose:[String] = []
var openDescription:String = ""
if let attractionsArray = orgJson as? NSArray{
if let attraction = attractionsArray[0] as? NSDictionary{
if let openHours = attraction["OpeningHours"] as? NSDictionary{
if let day = openHours["Monday"] as? NSDictionary{
if let open = day["From"] as? String{
monOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
monClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Tuesday"] as? NSDictionary{
if let open = day["From"] as? String{
tueOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
tueClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Wednesday"] as? NSDictionary{
if let open = day["From"] as? String{
wedOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
wedClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Thursday"] as? NSDictionary{
if let open = day["From"] as? String{
thuOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
thuClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Friday"] as? NSDictionary{
if let open = day["From"] as? String{
friOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
friClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Saturday"] as? NSDictionary{
if let open = day["From"] as? String{
satOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
satClose = close.componentsSeparatedByString(":")
}
}
if let day = openHours["Sunday"] as? NSDictionary{
if let open = day["From"] as? String{
sunOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"] as? String{
sunClose = close.componentsSeparatedByString(":")
}
}
if let desc = openHours["OpeningHoursGenericExceptions"] as? String{
openDescription = desc
}
}
}
}
XCTAssertEqual(monOpen, ["1","2","3"], "")
}
}
}
}
func testJSONBinding() {
measureBlock {() -> Void in
for _ in 0 ..< 400 {
autoreleasepool {
var monOpen:[String] = []
var monClose:[String] = []
var tueOpen:[String] = []
var tueClose:[String] = []
var wedOpen:[String] = []
var wedClose:[String] = []
var thuOpen:[String] = []
var thuClose:[String] = []
var friOpen:[String] = []
var friClose:[String] = []
var satOpen:[String] = []
var satClose:[String] = []
var sunOpen:[String] = []
var sunClose:[String] = []
var openDescription:String = ""
let openHours = json[0]["OpeningHours"]
var day:JSON
day = openHours["Monday"]
if let open = day["From"].string {
monOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
monClose
= close.componentsSeparatedByString(":")
}
day = openHours["Tuesday"]
if let open = day["From"].string {
tueOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
tueClose = close.componentsSeparatedByString(":")
}
day = openHours["WednesDay"]
if let open = day["From"].string {
wedOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
wedClose = close.componentsSeparatedByString(":")
}
day = openHours["Thursday"]
if let open = day["From"].string {
thuOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
thuClose = close.componentsSeparatedByString(":")
}
day = openHours["Friday"]
if let open = day["From"].string {
friOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
friClose = close.componentsSeparatedByString(":")
}
day = openHours["Saturday"]
if let open = day["From"].string {
satOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
satClose = close.componentsSeparatedByString(":")
}
day = openHours["Sunday"]
if let open = day["From"].string {
sunOpen = open.componentsSeparatedByString(":")
}
if let close = day["To"].string {
sunClose = close.componentsSeparatedByString(":")
}
XCTAssertEqual(monOpen, ["1","2","3"], "")
}
}
}
}
}
Uscite:
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testJSONBinding]' measured [Time, seconds] average: 0.804, relative standard deviation: 5.592%, values: [0.835687, 0.814827, 0.819685, 0.841900, 0.764961, 0.845202, 0.691442, 0.779255, 0.818213, 0.830698], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testJSONSubscript]' measured [Time, seconds] average: 4.247, relative standard deviation: 3.496%, values: [4.019640, 4.004123, 4.146146, 4.194535, 4.487171, 4.300971, 4.310613, 4.408405, 4.318354, 4.279362], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testNativeBinding]' measured [Time, seconds] average: 0.223, relative standard deviation: 2.773%, values: [0.221099, 0.227395, 0.218860, 0.225989, 0.227128, 0.222370, 0.229956, 0.214535, 0.210818, 0.229868], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testNativeSubscript]' measured [Time, seconds] average: 0.362, relative standard deviation: 17.528%, values: [0.346285, 0.316185, 0.333650, 0.339416, 0.330243, 0.354034, 0.378730, 0.269519, 0.486904, 0.467607], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
- tuo SwiftyJSON: 4.247
- nativa: 0,223
- mio SwiftyJSON: 0,804
- mia nativa: 0,362
A proposito, se fossi in te, vorrei fare qualcosa di simile:
if let hours = orgJson[0]?["OpeningHours"] as? NSDictionary {
let openDescription = hours["OpeningHoursGenericExceptions"] as? String ?? ""
let monOpen = hours["Monday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let monClose = hours["Monday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let tueOpen = hours["Tuesday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let tueClose = hours["Tuesday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let wedOpen = hours["Wednesday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let wedClose = hours["Wednesday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let thuOpen = hours["Thursday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let thuClose = hours["Thursday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let friOpen = hours["Friday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let friClose = hours["Friday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let satOpen = hours["Saturday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let satClose = hours["Saturday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
let sunOpen = hours["Sunday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? []
let sunClose = hours["Sunday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? []
// ...
}
E 'ragionevolmente veloce, sicuro, non così complicato.
Perché SwiftyJSON è lento?
In subscript
accesso, SwiftyJSON fa:
- controllo la chiave è
String
- pedice nuovo con
self[key:sub]
- controllo dell'oggetto sottostante è
NSDictionary
- pedice sottostante
NSDictionary
con la chiave in dotazione
- costruisci l'oggetto
JSON
con il risultato
return
Forse il compilatore ottimizza alcuni passi, ma "più lento di natale" è in qualche modo inevitabile :)
Grazie per una risposta molto approfondita! E con parametri di riferimento! Dato che sono molto nuovo su Swift (credo che molte persone siano :), la maggior parte della codifica è la prima prova-tentativi-ed-errore e ho fatto l'analisi JSON come suggerito nel file README di SwiftyJSON. Guardando i diversi esempi di metodi di parsing non mi pento di aver tirato fuori swifty dal mio progetto, la complessità del parsing "nativo" non è davvero un problema e aggiungendo la differenza di prestazioni non vedo swifty come opzione. – Simpa
Non intendo offesa al creatore di Swifty, penso che possa essere di grande utilità per molti sviluppatori. Ma googling 'quick parse json' dà quasi risultati con swifty mi ha dato l'impressione che fosse la strada da percorrere. Ma forse non è per tutti? :) – Simpa
@Simpa nel mondo Swift, non ci si può fidare di molti successi su Google. Si potrebbe avere l'impressione che Objective-C sia morto, Cocoapods è accettato come standard, ecc. Ecc ... in realtà, penso che molte di queste apparizioni siano problematiche. Tuttavia, SwiftyJSON è troppo lento da usare? Questa è un'altra domanda, ma se avevi ottenuto questi risultati in origine, potresti non averlo notato. –