XAMARIN SQLITE
PERFORMANCE
ROD HEMPHILL
MELBOURNE APP DEVELOPMENT
HTTP://MELBOURNEAPPDEVELOPMENT.COM
OCTOBER 2017
INTRODUCTION
• Purpose:
• How to get the best performance out of database reads for a client using
ZTE Blades.
• What is the overhead of reflection?
• What is the overhead of Automapper?
• How realistic are simulators and emulators with regards to SQLite
performance?
• Test environment:
• Standard iOS simulator (iPhone 7 running iOS 11)
• Genymotion Android emulator (Google Nexus 5 API23)
• (running on Mac 3.1Ghz i7, dual core, 16Gb memory)
• Iphone 6, ios 11, dual core, 1.4 Ghz
SQLITE IMPLEMENTATION (MY PREFERRED
IMPLEMENTATION)
• Nuget plugin: Sqlite.Net.async-PCL
• Asynchronous ORM tool (Object Relational Mapping).
• Implemented within a singleton behind an interface (“IDataService”):
• Singleton implemented using the Unity IoC container.
• Using an interface gives me flexibility to
• change in the future, and
• optimise independent of business logic.
• Three tier architecture:
• Persistence tier: everything behind the IDataServices interface (presentation
main focus).
• Business logic tier: models etc. (overhead of AutoMapper focuses
here).
• User Interface tier: Views and ViewModels.
DATA
• 1000 ActivityEvent DTO
records. (e.g. Bingo on
8/10/2017),
• Each with an embedded
activity type, location and
venue DTO.
• With a many-to-many list
of personnel who will
conduct the event.
• Total of about 5300
reads.
TESTS
10 tests run against the 4 environments:
A. Write speed.
B. Populate foreign key records using reflection.
C. No reflection.
D. Using 4 concurrent threads.
E. User Automapper to populate Model records from DTOs.
F. User Automapper with concurrent threads.
G. Assign fields directly rather than Automapper.
H. Assign fields with concurrent threads.
I. Direct ORM call records = await db.GetAllAsync<T>()
J. Query string call records = await db.QueryAsync<T>(“Select * from
table {0}”,name)
RESULTS
Pogram A Program B Program C Program D Program E Program F Program G Program H Program I Program J
Writes Reflection No reflection
Concurrent
threads
Automapper
Automapper
/ concurrent
No
Automapper
No
Automapper /
concurrent
direct query
iOS
rec/se
c 60 270 597 605 2,232 2,132 84,968 86,339 569 578
second
s 39.003 19.861 8.966 8.848 2.398 2.510 0.063 0.062 2.110 2.077
records 2330 5353 5353 5353 5353 5353 5353 5353 1200 1200
iOS Simulator rec/sec 291 625 604 2,949 2,919 24,697 22,137
second
s 8.000 1.599 1.657 0.339 0.343 0.040 0.045
records 2330 1000 1000 1000 1000 1000 1000
Android
rec/se
c 18 7 19 24 1,687 1,965 17,529 16,932 63 63
second
s 126.486 146.479 51.807 40.918 3.172 2.725 0.305 0.316 16.069 15.944
records 2330 5353 5353 5353 5353 5353 5353 5353 1010 1010
Android
Emulator rec/sec
78 159 2,560 3,231 4,311 3,595
second
s 12.890 6.288 0.391 0.309 0.232 0.278
records 1000 1000 1000 1000 1000 1000
SUMMARY
iOS Automapper overhead: 2.34
seconds per 1000
records 20.5%
Overhead on whole read
process
Reflection overhead: 10.89
seconds per 1000
records 55% Improvement
Concurrent processing
benefit: 0.12
seconds per 1000
records 1% Improvement
iOS Simulator Automapper overhead: 0.30
seconds per 1000
records 15.4%
Overhead on whole read
process
Concurrent processing
benefit: -0.06
seconds per 1000
records -4% Improvement
Android Automapper overhead: 2.87
seconds per 1000
records 5.2%
Overhead on whole read
process
Reflection overhead: 94.67
seconds per 1000
records 65% Improvement
Concurrent processing
benefit: 10.89
seconds per 1000
records 21% Improvement
Android
Emulator Automapper overhead: 0.16
seconds per 1000
records 1.1%
Overhead on whole read
process
Concurrent processing
benefit: 6.53
seconds per 1000
records 48% Improvement
MY CONCLUSIONS
1. Don’t use reflection.
2. Automapper has a significant overhead.
3. Concurrent processing has significant benefits on Android ZTE
devices …
4. Android ZTE very much slower than the iPhone (although we rarely
get a choice about device deployment)
5. The emulators and simulators a reasonable representation of devices
– relative to themselves. (i.e. a 10% performance improvement on an
emulator can expect a 10 improvement on a device)
6. There is no difference between generic ORM calls and ORM query
string calls.
Questions?

Xamarin Sqlite Performance

  • 1.
    XAMARIN SQLITE PERFORMANCE ROD HEMPHILL MELBOURNEAPP DEVELOPMENT HTTP://MELBOURNEAPPDEVELOPMENT.COM OCTOBER 2017
  • 2.
    INTRODUCTION • Purpose: • Howto get the best performance out of database reads for a client using ZTE Blades. • What is the overhead of reflection? • What is the overhead of Automapper? • How realistic are simulators and emulators with regards to SQLite performance? • Test environment: • Standard iOS simulator (iPhone 7 running iOS 11) • Genymotion Android emulator (Google Nexus 5 API23) • (running on Mac 3.1Ghz i7, dual core, 16Gb memory) • Iphone 6, ios 11, dual core, 1.4 Ghz
  • 3.
    SQLITE IMPLEMENTATION (MYPREFERRED IMPLEMENTATION) • Nuget plugin: Sqlite.Net.async-PCL • Asynchronous ORM tool (Object Relational Mapping). • Implemented within a singleton behind an interface (“IDataService”): • Singleton implemented using the Unity IoC container. • Using an interface gives me flexibility to • change in the future, and • optimise independent of business logic. • Three tier architecture: • Persistence tier: everything behind the IDataServices interface (presentation main focus). • Business logic tier: models etc. (overhead of AutoMapper focuses here). • User Interface tier: Views and ViewModels.
  • 4.
    DATA • 1000 ActivityEventDTO records. (e.g. Bingo on 8/10/2017), • Each with an embedded activity type, location and venue DTO. • With a many-to-many list of personnel who will conduct the event. • Total of about 5300 reads.
  • 5.
    TESTS 10 tests runagainst the 4 environments: A. Write speed. B. Populate foreign key records using reflection. C. No reflection. D. Using 4 concurrent threads. E. User Automapper to populate Model records from DTOs. F. User Automapper with concurrent threads. G. Assign fields directly rather than Automapper. H. Assign fields with concurrent threads. I. Direct ORM call records = await db.GetAllAsync<T>() J. Query string call records = await db.QueryAsync<T>(“Select * from table {0}”,name)
  • 6.
    RESULTS Pogram A ProgramB Program C Program D Program E Program F Program G Program H Program I Program J Writes Reflection No reflection Concurrent threads Automapper Automapper / concurrent No Automapper No Automapper / concurrent direct query iOS rec/se c 60 270 597 605 2,232 2,132 84,968 86,339 569 578 second s 39.003 19.861 8.966 8.848 2.398 2.510 0.063 0.062 2.110 2.077 records 2330 5353 5353 5353 5353 5353 5353 5353 1200 1200 iOS Simulator rec/sec 291 625 604 2,949 2,919 24,697 22,137 second s 8.000 1.599 1.657 0.339 0.343 0.040 0.045 records 2330 1000 1000 1000 1000 1000 1000 Android rec/se c 18 7 19 24 1,687 1,965 17,529 16,932 63 63 second s 126.486 146.479 51.807 40.918 3.172 2.725 0.305 0.316 16.069 15.944 records 2330 5353 5353 5353 5353 5353 5353 5353 1010 1010 Android Emulator rec/sec 78 159 2,560 3,231 4,311 3,595 second s 12.890 6.288 0.391 0.309 0.232 0.278 records 1000 1000 1000 1000 1000 1000
  • 7.
    SUMMARY iOS Automapper overhead:2.34 seconds per 1000 records 20.5% Overhead on whole read process Reflection overhead: 10.89 seconds per 1000 records 55% Improvement Concurrent processing benefit: 0.12 seconds per 1000 records 1% Improvement iOS Simulator Automapper overhead: 0.30 seconds per 1000 records 15.4% Overhead on whole read process Concurrent processing benefit: -0.06 seconds per 1000 records -4% Improvement Android Automapper overhead: 2.87 seconds per 1000 records 5.2% Overhead on whole read process Reflection overhead: 94.67 seconds per 1000 records 65% Improvement Concurrent processing benefit: 10.89 seconds per 1000 records 21% Improvement Android Emulator Automapper overhead: 0.16 seconds per 1000 records 1.1% Overhead on whole read process Concurrent processing benefit: 6.53 seconds per 1000 records 48% Improvement
  • 8.
    MY CONCLUSIONS 1. Don’tuse reflection. 2. Automapper has a significant overhead. 3. Concurrent processing has significant benefits on Android ZTE devices … 4. Android ZTE very much slower than the iPhone (although we rarely get a choice about device deployment) 5. The emulators and simulators a reasonable representation of devices – relative to themselves. (i.e. a 10% performance improvement on an emulator can expect a 10 improvement on a device) 6. There is no difference between generic ORM calls and ORM query string calls.
  • 9.