Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[swift]5万件のデータから高速な検索機能

解決したいこと

Swiftで、ローカルの5万件のデータから、PrimaryKey(文字列)に対応する文字列を取得する機能を実装しています。
データ:[文字列(PrimaryKey),文字列]

現在は、RealmSwiftを使用して100万回の検索が約10秒かかります。
100万回の検索を3秒で実施したいです。

知りたいこと

・パフォーマンスを満たせる方法
ざっくりとしていますが、何かしらご教授いただければと思います。
そもそもRealmSwiftで良いのか? データは、swift内部でDictionary型やJson型でデータを管理するべきか?

・RealmsSwiftの最適なデータ検索方法
PrimaryKeyを100万回呼び出す時、一件毎検索していますがまとめて検索した方が早いのか?

自分で試したこと

・RealmSwift
Realmに5万件のデータを登録し、PrimaryKeyで一件毎検索する機能を実装しました。
この方法で100万回の検索で約10秒かかりました。

realm.object(ofType: オブジェクト.self, forPrimaryKey: "文字列")

・Dictionary型で定義
データをDictionary型で定義し呼び出そうとしましたが、重すぎてビルドすらできませんでした。、

0 likes

1Answer

下記コードでDictionaryの性能を調べました。

import Foundation

let DIGIT = ("0123456789" + "abcdefghijklmnopqrstuvwxyz" +  "ABCDEFGHIJKLMNOPQRSTUVWXYZ").map { String($0) }

let numToStr: (_ N: Int) -> String = {
    var value = ""
    var n = $0
    while n > 0 {
        value += DIGIT[n % DIGIT.count]
        n /= DIGIT.count
    }
    return String(value.reversed())
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}

let main: () = {
    print("Ready!")
    
    var dict = [String: String]()
    
    let makeData50000 = measureTimeSeconds {
        while dict.count < 50_000 {
            let num = (0 ... 200_000).randomElement() ?? 0
            let key = numToStr(num)
            dict[key] = "\(num)"
        }
    }
    print(dict.count, makeData50000)

    var cnt = 0, hit = 0
    let randomSearch1000000 = measureTimeSeconds {
        while cnt < 1_000_000 {
            let num = (0 ... 200_000).randomElement() ?? 0
            let key = numToStr(num)
            if dict[key] != nil { hit += 1 }
            cnt += 1
        }
    }
    print(cnt, hit, randomSearch1000000)
}()

当方は2019製Intel Macですが、以下の性能でした。

Ready!
50000 0.11836099624633789
1000000 250951 1.7343389987945557
Program ended with exit code: 0

・5万件のデータをランダムに作成する時間:0.118秒
・5万件のデータをランダムに100万回検索する時間:1.734秒(ヒット率25%)

参考になるでしょうか?

0Like

Your answer might help someone💌