EF Core SQLite медленный запуск производительности на Xamarin
Я столкнулся с медленным запуском моего приложения Xamarin.Android.
Первое создание DbContext занимает ~4,5 секунды (в контексте 24 таблицы). Сначала я подумал, что причина в том, что EF Core требуется время для сканирования классов сущностей из DbContext и построения модели (это имеет смысл для большого DbContext).
Итак, я создал тестовый DbContext только с одной таблицей, чтобы проверить взаимосвязь между временем создания модели и количеством таблиц в модели:
public class Log
{
[Key]
public int EntityId { get; set; }
public string Timestamp { get; set; }
public string Level { get; set; }
public string Exception { get; set; }
public string RenderedMessage { get; set; }
public string Properties { get; set; }
}
public class ApplicationLogDbContext : DbContext
{
public ApplicationLogDbContext(DbContextOptions<ApplicationLogDbContext> options)
: base(options) { }
public DbSet<Log> Logs { get; set; }
}
Код теста DbContext:
var options = new DbContextOptionsBuilder<ApplicationLogDbContext>()
.UseSqlite("Data Source=/storage/emulated/0/Android/data/***/files/ApplicationLog.db")
.Options;
var logContext = new ApplicationLogDbContext(options);
logContext.Database.EnsureCreated();
На моем Samsung Galaxy S7 выполнение этого кода занимает 3,3 секунды. Этот тест показал нецелесообразность пробовать некоторые решения:
- Используйте меньше классов сущностей (уменьшите связи между таблицами);
- Разделите одно приложение DbContext на несколько небольших контекстов.
Я также узнал, что:
- EF Core не имеет автоматической миграции (отключать ее не нужно);
- Я удалил подход "сначала код", но он лишь частично помог сократить время инициализации DbContext до 4 секунд;
- Если я удалю строку с помощью EnsureCreated, время выполнения первого запроса увеличится на то же время;
- Подобных проблем много (здесь GitHub), но решения у них нет. О таких проблемах сообщалось даже для EF6;
- После установки Microsoft.EntityFrameworkCore.Sqlite 5.0.0-preview.6.20312.4 существенных изменений не заметил (у приложения такое же время выполнения: ~ 3,3 секунды);
- PRAGMA journal_mode=WAL; увеличена скорость инициализации (EF Core 2.2). Это нестабильно, но иногда время инициализации сокращается на 300-400 мс.
- Если в приложении есть 2 DbContext для разных баз данных (1-я с одной сущностью, 2-я с 25 сущностями), время инициализации EF Core для второго контекста резко сокращается до ~1 секунды. Инициализация первого контекста все еще медленная;
- Инициализация выполняется быстрее (~30%) без подключенного сеанса отладки.
Пример с EF Core 5 Preview 6 GitHub
Какой подход я могу использовать, чтобы как-то скрыть это время инициализации от пользователя, но получить данные для основного действия?
Есть ли какие-либо советы по настройке, которые могут помочь увеличить время инициализации конфигурации по умолчанию?
Улучшится ли производительность при запуске.NET 5?