2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftでのJSONのパースは構造体?辞書?

Last updated at Posted at 2022-04-22

今回はJSONをパースする際、どっちの方がいいのかが気になったので検証してみました。
検証が甘いかもしれませんが多めにみてください

どっちが楽か

これは検証するまでもなく圧倒的に辞書の勝利です

JSONの情報量が少なければ構造体も苦ではありませんが返ってくるKeyの数が300件+ネストも深いともなってくると苦行です

速度

実はこれがメインです
構造体の方が早いのは予想がつくのですがどのくらい差があるのかが気になったので検証してみました。

計測の方法
こちらの記事の計測方法を使いました

取得するJSON
TwitterAPIのJSONを使用します

https://api.twitter.com/1.1/users/show.json

HTTP通信

    // 構造体でパース
    public func user_info(screen_name: String) async throws -> UserInfo {
        let guest_token = try await generate_guest_token().guest_token
        let url = URL(string: "https://api.twitter.com/1.1/users/show.json?screen_name=\(screen_name)")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.addValue("Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", forHTTPHeaderField: "authorization")
        request.addValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", forHTTPHeaderField: "User-Agent")
        request.addValue(guest_token, forHTTPHeaderField: "x-guest-token")
        let (data, _) = try await URLSession.shared.data(for: request)
        let user_info = try JSONDecoder().decode(UserInfo.self, from: data)
        return user_info
    }

    // 辞書でパース
    public func user_info(screen_name: String) async throws -> [String: Any] {
        let guest_token = try await generate_guest_token().guest_token
        let url = URL(string: "https://api.twitter.com/1.1/users/show.json?screen_name=\(screen_name)")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.addValue("Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", forHTTPHeaderField: "authorization")
        request.addValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", forHTTPHeaderField: "User-Agent")
        request.addValue(guest_token, forHTTPHeaderField: "x-guest-token")
        let (data, _) = try await URLSession.shared.data(for: request)
        let user_info = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        return user_info ?? [:]
    }

こんな感じです
HTTP通信の処理に違いはありません

こちらが作成した構造体です
長いので画像だけ載せます
スクリーンショット 2022-04-22 13.39.02.png

いざ検証!!

構造体と辞書ともに30回の処理速度を計測して平均を比較してみたいと思います。

回数 構造体 辞書
1 0.421766996383667 0.48710501194000244
2 0.4457869529724121 0.4717440605163574
3 0.44557106494903564 0.4696040153503418
4 0.42271196842193604 0.49256694316864014
5 0.44592905044555664 0.47148895263671875
6 0.4459249973297119 0.4711570739746094
7 0.424003005027771 0.49338698387145996
8 0.42439305782318115 0.4934580326080322
9 0.4237560033798218 0.47139596939086914
10 0.42368102073669434 0.4724550247192383
11 0.42344892024993896 0.4737999439239502
12 0.42438793182373047 0.4938730001449585
13 0.42647695541381836 0.47372591495513916
14 0.4473719596862793 0.47147297859191895
15 0.42362499237060547 0.4707820415496826
16 0.44748401641845703 0.4732930660247803
17 0.4240630865097046 0.471979022026062
18 0.4490799903869629 0.4713670015335083
19 0.42538297176361084 0.49446797370910645
20 0.4752979278564453 0.49462997913360596
21 0.431210994720459 0.502689003944397
22 0.43148505687713623 0.4725559949874878
23 0.4548109769821167 0.4729820489883423
24 0.4322160482406616 0.4967290163040161
25 0.4342590570449829 0.4732940196990967
26 0.4346250295639038 0.4735100269317627
27 0.43521392345428467 0.47393298149108887
28 0.43390095233917236 0.4742039442062378
29 0.4347410202026367 0.49745798110961914
30 0.44629597663879395 0.47441208362579346
平均 0.4352967302 0.479850669702

結果

構造体は辞書より0.04455393950200004秒速い

結論

楽さを求める人
圧倒的に辞書がおすすめです!!

速度を求める人
1回だけ取得する人 -> 辞書がおすすめです
複数回の取得する人 -> 構造体がおすすめです

1回の取得だけなら人間には分からないレベルの差です
しかし、複数回取得する場合、数秒の差が生まれます

ユーザーにとってローディングの1秒はかなり大きいです
構造体を作成するのは苦行ですがユーザーの1秒の為に頑張りましょう!!

追記(2022/9/10)

Codableに準拠した構造体を自動で生成してくれるサイト見つけました。
JSONをペーストするだけで自動生成してくれます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?