2

私たちの状況は次のとおりです。

特定の時間にユーザー定義のディレクトリをスキャンするネイティブ コードがいくつかあります。目標は、特定の種類のファイルに関するデータを収集し、そこから SQLite データベースを構築することです。照会するファイルが数万ある可能性があります。

問題は、ファイルが見つかるたびに、そのファイルについて収集されたデータが、Android SDK によって提供される SQLite クラスを介してデータベースにコミットされる前に、JNI 境界を越えて Java ランドに導かれなければならないことです。これには時間がかかりすぎます。

提案された解決策は、SQLite ソース コードをダウンロードし、それをプロジェクトにリンクして、ここで説明されているようにデータベースをネイティブに構築することです: SQLite with Android NDK。これにより、C++ レイヤーから Java レイヤーにデータを渡すのにかかる時間が完全になくなります。

問題は、これが行われた場合、Android SDK (Java レイヤー) を引き続き使用して、データベースを開いたり、通常どおり Cursor オブジェクトを取得したりできるかどうかです。データベースを非常にシンプルに保つことができます。外部キー、トリガー、制約などはありません。インデックスは非常に望ましいですが。

JNI 境界を越えてデータを移動するために、パイプとソケットを検討しました。ただし、名前付きパイプは Fat32 ファイル システムではサポートされていません (そのため、ユーザーがアプリケーションを Fat32 フォーマットの SD カードに移動した場合、これは使用できません)。マニフェストに疑わしいと思われるインターネットアクセス許可を含める必要があるため、ソケットも使用できません。

誰かがこれに関する情報を持っている場合は、ぜひご連絡ください。

どうもありがとう、P.

4

1 に答える 1

4

フォローアップとして、私たちは思い切って、最新の SQLite Amalgamation (3.7.13) ソース コードをコンパイルしたテスト アプリケーションをまとめました。Android Java SDK を介して、ネイティブに作成されたデータベースと実際にインターフェースできることがわかりました。

パフォーマンスに関しては、これは大きな飛躍でした! ネイティブ レイヤーにレコードを挿入することで、パフォーマンスが大幅に向上することがわかりました。以前は、複雑でないデータベースに 20,000 レコードを挿入するのに約 4 分かかりました。簡単なプロファイリングを行ったところ、ネイティブ層から Java 層へのデータの受け渡しに 4 分間のほとんどすべてが費やされたことがわかりました。

現在、挿入には 4 ~ 6 秒かかります。通常どおり、Java API を使用してデータベースを開いたり、クエリを実行したりすることもできます。

注意すべきパフォーマンスの微調整は、トランザクションと、以下を使用してジャーナルをメモリに移動することです。

pragma journal_mode=memory;

安定性の理由から、同期をオフにしないことに決めました。さらに、すでに達成したパフォーマンスに満足しています。

うまくいけば、他の人がこのアドバイスを役に立つと思うでしょう。

P

于 2012-08-05T01:21:56.650 に答える