質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

0回答

568閲覧

約15万行のIPアドレスのリストを読み込んで使用する場合のデータ構造

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2021/10/05 19:29

Javaで15万行ほどのIPアドレスと国の対応が書いたCSVを読み込んでおき、
アクセス元のIPとその読み込んだリストを照らし合わせて処理をしたいと考えています。
その場合、データ構造としてはハッシュマップを使うのが最適なのでしょうか?
また、そのときはサイズを指定した方が速いと聞いたのですが、
例えば20万とかの多めを指定すればよいのでしょうか?それとも少ないくらいの方が良いのでしょうか?
よろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/10/05 19:57

「考えている」「最適かどうか」「聞いた」といったぼんやりしたものでは無く、実際のデータが手元にお有りであれば、想定されるコード(を極力「最適化」したもの)を書いて実行・計測し、そのコードや結果/目標をご提示の上で、そこからさらに「こうしたいがどう出来るか/出来ないか」という形でご質問されたほうが、回答側も考えたものを試して比較したりと判断し易いように思いますが、如何でしょうか。
takasima20

2021/10/05 20:49

どれくらいのターンアラウンドタイムを期待しているかによるんじゃ? シビアじゃないならアクセスはデータベースに丸投げしてもいいし、そうじゃなかったら自前でなんとかするしかないってことで、そのへんのコストバランスは(背景を知らない)他人じゃ分からんスよ。
dodox86

2021/10/05 21:10

> そのときはサイズを指定した方が速いと聞いたのですが、例えば20万とかの多めを指定すればよいのでしょうか? ? これはどのような状況での速い・遅いの話でしょう。ハッシュマップを生成するときに最終的な要素数より小さいサイズで用意しておくと、拡げる処理に時間がかかる(かもしれない)話、でしょうかね。いずれにせよCSVをもとにIPアドレスをキー、国の対応を値とするだけなら簡単そうなものなのですから、まずご自身でコードを書いて、ご自身の環境で試してみるのが先決です。
takasima20

2021/10/06 12:10

あと、こんだけ回答にするのもあれなので… もし懸念事項がデータ増加時の再割り当てのことだったら今回は関係なさそうスね。
dameo

2021/10/07 04:51

最適かどうかは私には分かりませんが(分からないので回答はできません)、経験的にはHashMapが普通だと思います。 速さという点では、初期サイズを指定した方が速いはずですが、そこが支配的になるかどうかは不明なので何とも言えませんし、最近のJVMなどは繰り返すほど速くなるので、正確な計測は出来ません。 HashMapを使用する場合は、初期サイズをデフォルトの係数0.75で割った数に1足すくらいにしておくことで、テーブルの拡張を抑えることができ、メモリ効率はいいでしょう。 上記を踏まえ、サンプルコードを用意しました。 import java.util.*; import java.util.stream.Stream; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.function.Supplier; public class Main { private static Random rand = new Random(); private static String getRandomIPv4String() { return Stream.generate(()->String.valueOf(rand.nextInt(256))) .limit(4) .collect(Collectors.joining(".")); } public static double measure(String[] array, Supplier<Map<String,String>> mapSupplier) { final int N = array.length; long nano = System.nanoTime(); Collector<String, ?, Map<String,String>> colloector = mapSupplier != null ? Collectors.toMap( e -> e, // key e -> e, // value (e1, e2) -> e1, // 先優先 mapSupplier // 使用するマップ生成 ) : Collectors.toMap( e -> e, // key e -> e, // value (e1, e2) -> e1 // 先優先 ); Map map = Arrays.stream(array).collect(colloector); nano = System.nanoTime() - nano; double sec = (double)nano / 1000000000L; //System.out.println(map); //System.out.println(map.size()); //System.out.println(map.getClass().getName()); System.out.println(sec); return sec; } public static void main(String[] args) throws Exception { //final int N = 15; final int N = 150000; String[] array = Stream.generate(()->getRandomIPv4String()).limit(N).toArray(String[]::new); final int TEST_COUNT = 5; System.out.println(Stream.generate(()->measure(array, () -> new HashMap<String,String>((int)((float)N/0.75+1)))).limit(TEST_COUNT).mapToDouble(e->e).average()); System.out.println(Stream.generate(()->measure(array, null)).limit(TEST_COUNT).mapToDouble(e->e).average()); } } paiza.ioで実行した結果は以下のとおりです。 0.044941748 0.039713869 0.044337646 0.017000638 0.030105166 OptionalDouble[0.0352198134] 0.045640248 0.015848375 0.040869445 0.02239253 0.008865428 OptionalDouble[0.0267232052] ご参考までに。
退会済みユーザー

退会済みユーザー

2021/10/07 05:24

>dameoさん >最適かどうかは私には分かりませんが(分からないので回答はできません)、経験的にはHashMapが普通だと思います。 あまり経験がないのでトンチンカンな方向に行ってないか確認したかったため、HashMapで問題なさそうで良かったです。 >初期サイズをデフォルトの係数0.75で割った数に1足すくらいにしておくことで、テーブルの拡張を抑えることができ、 テーブルの拡張で多少時間がかかるので初期サイズ指定した方が良いという記事は見たのですが、 あまり詳しく書いてなかったので、一般的な値助かります。 サンプルコードもありがとうございます。 paizaで何度か実行してみたら上記ほどの差にはならず、多少ブレがあるみたいですね コードを見ると上が初期サイズ指定した方だと思ったのですが、 これは逆に遅くなっているということでしょうか?
dameo

2021/10/07 05:43

> テーブルの拡張で多少時間がかかるので初期サイズ指定した方が良いという記事は見たのですが、 > あまり詳しく書いてなかったので、一般的な値助かります。 0.75は別に一般的な値というわけではなく、HashMapのデフォルト値です。 https://docs.oracle.com/javase/jp/8/docs/api/java/util/HashMap.html > コードを見ると上が初期サイズ指定した方だと思ったのですが、 > これは逆に遅くなっているということでしょうか? 数字だけ見るとそのとおりです。元は順番逆にしていたのですが、上に書いた方が数字的に不利なのでこうしています。 この実験においては有為な差がないというか、誤差の方が大きいと個人的には見ています。定性的にはループで試行回数(TEST_COUNT)を増やすとどちらも時間が減っていき差も詰まるようでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問