Как я могу улучшить этот метод загрузки объектов с ORMLite на Android? - PullRequest
2 голосов
/ 19 марта 2012

Я загружаю набор объектов (и их сторонних объектов) с помощью ormlite 4.35 на Android. Время (в эмуляторе) от 16 до 19 секунд для синхронизации в методе getAllCragsWithLocation() ниже.

В базе данных 590 Краг, а у 40 нет местоположения.

Есть несколько зарегистрированных строк, таких как

03-19 11:03:54.441: I/dalvikvm(1156): Jit: resizing JitTable from 1024 to 2048
03-19 11:03:55.531: D/dalvikvm(1156): GC_CONCURRENT freed 544K, 37% free 5174K/8199K, external 731K/1109K, paused 6ms+11ms

Должен ли я загружать объекты другим способом? Выполнение запроса в командной строке sqlite3 занимает примерно одну сотую секунды ...

public List<Crag> getAllCragsWithLocation() {
        Log.i(TAG,"beginning db calls");
        long startQuery = System.currentTimeMillis();
        QueryBuilder<Crag,Integer> queryBuilder = helper.getCragDao().queryBuilder();
        List<Crag> results = new ArrayList<Crag>();
        try {
            queryBuilder.where().isNotNull("location_id");
            Log.i(TAG,queryBuilder.prepareStatementString());
            PreparedQuery<Crag> preparedQuery = queryBuilder.prepare();
            results = helper.getCragDao().query(preparedQuery);
        } catch (android.database.SQLException e) {
            Log.e(TAG,e.toString());
        } catch (SQLException e) {
            Log.e(TAG,e.toString());
        }
        Log.i(TAG,"ending query after "+((System.currentTimeMillis()-startQuery)/1000)+" seconds");
        return results;
    }

Объект скалы (упрощенный):

@DatabaseTable
    public class Crag {
        public Crag() {
            //ormlite requires a no-arg constructor?
            guidebooks = new ArrayList<Guidebook>();
        }

        @DatabaseField(id=true) private int id;
        @ForeignCollectionField(eager = true)
        private Collection<Guidebook> guidebooks;
        @DatabaseField(foreign=true, foreignAutoRefresh = true, index=true)
        private uk.co.bmc.rad.models.Location location;
        @DatabaseField(foreign=true,foreignAutoRefresh=true)
        private SubRegion subRegion;
    }

Иностранные объекты - намного более простые классы, чем Крэг. Для целей отображения необходимо указать только местоположение в том месте, где объекты загружаются из базы данных, но я использую посторонние объекты при сравнении на равенство, поэтому ...

Возврат из getAllCragsWithLocation() повторяется для подготовки к добавлению к MapOverlay. Время этого процесса занимает менее секунды.


UPDATE: Я только что поменялся в DB4O для сравнения, и он сравнительно быстро загружает все скалы по сравнению, поэтому я думаю, что я пойду с этим.


ОБНОВЛЕНИЕ ОБНОВЛЕНИЕ: Вместо того, чтобы быстро поменяться местами в DB4O, я потратил больше времени на их сравнение.

В JUnit 3 AndroidTestCase, если я вставляю одну запись в базу данных и затем запрашиваю ее напрямую, то ORMLite и DB4O занимают около секунды (всего), чтобы вставить и вернуть объект.

Если я запускаю процесс для вставки 590 объектов, тогда ORMLite занимает около 24 секунд, а DB40 - около 40.

Сразу после этой вставки, если я вызываю getAllCragsWithLocation (), а затем getAllCrags (), DB40 занимает 7 секунд, а затем 0 секунд, чтобы вернуть список Crags, поэтому я предполагаю, что он имеет кэш, который ускоряет второй запрос

Хотя ORMLite занимает около 7 секунд для обоих запросов.

Так что на самом деле в нем очень мало


ОБНОВЛЕНО ОБНОВЛЕНО ОБНОВЛЕНО: Взял сегодня Transformer Prime и просто запустил приложение на нем и скалы загрузились за 1 секунду по сравнению с 7 на эмуляторе.

Поскольку мне уже удалось получить синтаксис запроса ormlite; может вернуться к raw sql, а структура таблицы sqlite более переносима, я буду придерживаться ormlite над db4o.

Ответы [ 2 ]

4 голосов
/ 19 марта 2012

Я действительно удивлен, что это занимает столько времени.

    @ForeignCollectionField(eager = true)
    private Collection<Guidebook> guidebooks;
    @DatabaseField(foreign=true, foreignAutoRefresh = true, index=true)
    private uk.co.bmc.rad.models.Location location;
    @DatabaseField(foreign=true,foreignAutoRefresh=true)
    private SubRegion subRegion;

Каждое из этих полей сгенерирует другой запрос к базе данных, который займет время, хотя я не ожидаю секунд.ORMLite не очень умел использовать JOIN для удовлетворения нетерпеливо выбранных удаленных объектов.

Одна вещь, которую стоит попробовать, - это использовать процесс table-config, чтобы обойти собачью реализацию Android, собаку с медленным отражением при создании реализаций DAO.См. Документы для этого:

http://ormlite.com/docs/table-config

Мне было бы интересно, если бы вы выяснили это, хотя я понимаю, если вам нужно переключиться на какой-то другойпакет, чтобы получить работу.

0 голосов
/ 19 марта 2012

Я думаю, вы должны рассмотреть возможность использования ContentProvider.Я сделал приложение, манипулирующее 2k строк, но запрос и восстановление объекта выполняются менее чем за 10 секунд на эмуляторе

...