Лучше вернуть List из HashMap или сохранить List в памяти? - PullRequest
0 голосов
/ 07 мая 2018

Я вижу много результатов для возврата List из HashMap, так что никаких проблем нет, но мне любопытно узнать, лучше ли всегда делать это по сравнению с сохранением объектов в списке в моем сценарии ниже.

У меня есть куча объектов Widget (имеющих id (UUID), title (String) и priority (int)) в одном классе, WidgetStore. Я собираюсь использовать их, чтобы заполнить RecyclerView. Fragment хочет список для представления, но у меня также есть метод для возврата одного виджета по id. Сохранение виджетов в списке означает, что я должен пройтись по ним в поисках одного с заданным id, поэтому я считаю, что гораздо быстрее иметь их в HashMap<UUID, Widget>. Мало того, что поиск по id быстр, но я также могу просто вернуть список object, когда его спросят. Это более или менее оптимально? Есть ли способ, которым я могу узнать для себя, не беспокоя тебя? (Вопрос для моего личного назидания, я пытаюсь немного лучше изучить внутреннюю работу.)

Вот класс для WidgetStore:

public class WidgetStore {
    private static WidgetStore sWidgetStore;
    // private final List<Widget> mWidgets; // Use hashmap instead, better?
    private final HashMap<UUID, Widget> mIdMap = new HashMap<>();

    public static WidgetStore get(Context context) {
        // Singleton: if one exists, return it; otherwise, create it
        if (sWidgetStore == null) {
            sWidgetStore = new WidgetStore(context);
        }
        return sWidgetStore;
    }

    private WidgetStore(Context context) {
        // Singleton: only access this class with get()

        // mWidgets = new ArrayList<>(); // Use hashmap instead

        // Widget factory
        for (int i = 0; i < 10000; i++) {
            Widget widget = new Widget();
            widget.setTitle("Widget #" + i);
            widget.setPriority((int) (Math.random() * 100d) % 3); // Random-ish-ly
            // mWidgets.add(widget); // Use hasmap instead
            mIdMap.put(widget.getId(), widget);
        }
    }

    public List<Widget> getWidgets() {
        // TODO find out if faster to always create new list from hashmap or
        // also keep a list around in memory (seems fast on good hardware...)
        List<Widget> list = new ArrayList<>(mIdMap.values());
        return list;
    }

    public Widget getWidget(UUID id) {
        Widget widget = mIdMap.get(id);
        if (widget == null) {
            return null;
        }
        return widget;
    }
}

1 Ответ

0 голосов
/ 07 мая 2018

Традиционно вы не должны сильно беспокоиться об оптимизации кода, пока не начнете разработку, и вы поймете, что есть проблема с производительностью. Но если вы узнаете о том, что хотите узнать больше о более оптимальном варианте, это звучит как HashMap или похожая карта.

Наличие метода для получения значений в виде списка может быть полезным в зависимости от того, знаете ли вы идентификатор для виджета, который вы хотите или нет, или если вам нужно проверить какое-либо другое свойство виджета, чтобы идентифицировать его.

Что касается самостоятельного профилирования, есть пара методов. Вы можете просто добавить некоторые инструкции Log, используя System.currentTimeMillis(), например:

long now = System.currentTimeMillis();
Widget widget = widgetStore.get(id);
long duration = System.currentTimeMillis() - now;
Log.i("WidgetStorePerformance", duration);

Это низкотехнологичное решение. Вы также можете посмотреть, как добавить вызовы метода Trace в код WidgetStore, который вы хотите профилировать.

public Widget getWidget(UUID id) {
    Trace.beginSection("WidgetStore");
    Widget widget = mIdMap.get(id);
    if (widget == null) {
        return null;
    }

    Trace.endSection();
    return widget;
}

Затем используйте этот инструмент

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...