Как я могу улучшить этот метод загрузки объектов с помощью ORMLite на Android?
Я загружаю набор объектов (и их сторонних объектов) с помощью 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 занимает около 100 секунды...
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
, Время этого процесса занимает меньше секунды.
ОБНОВЛЕНИЕ: я только что поменялся в 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 ответа
Я действительно удивлен, что это занимает так много времени.
@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. Смотрите документы для этого:
Мне было бы любопытно, если бы вы поняли это, хотя я понимаю, если вам нужно переключиться на какой-то другой пакет, чтобы начать работать.
Я думаю, вы должны рассмотреть возможность использования ContentProvider. Я сделал приложение, манипулирующее 2k строк, но запрос и регенерация объекта выполняются менее чем за 10 секунд на эмуляторе