Uploaded on

 

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
21,054
On Slideshare
0
From Embeds
0
Number of Embeds
12

Actions

Shares
Downloads
111
Comments
1
Likes
12

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. A look behind the scenes greenDAODroidcon Berlin 2012,Markus Junginger
  • 2. About me, Follow me Android developer since 2007 Founder of greenrobot.de, Munich @green_dao Most updates  @greenrobot_de Most important updates  +Markus Junginger  +greenrobot 
  • 3. Agenda What is greenDAO? – SQLite database – ORM – Code generation based on meta model Background info and „secret“ internals – Why code generation? – Performance Tweaks
  • 4. Problem with DB Development Database world  ||  Java world No object orientation Data access feels quite low levely A lot of boilerplate code for SQLite – SQL scripts, e.g.: CREATE TABLE, Queries – Cursor iterations – Parameter binding
  • 5. Common solution: ORM Java Object SQLite greenDAO Java Object Database Java Object ORM offers a higher level API – Read and write objects – CREATE TABLE done for you – Expressing Queries
  • 6. Example: SQLite vs. greenDAOString[] columns = { "note", "date_changed" };String[] idArgs = { String.valueOf(id) };SQLiteCursor cursor = (SQLiteCursor) db.query("notes", columns,"_id=?", idArgs, null, null, "note");try { // greenDAO if (cursor.getCount() != 1) { Note note = noteDao.load(id); throw new Exception("Unexpected count: " +cursor.getCount()); updateUi(note.getNote(), note.getDate()); } cursor.moveToNext(); String note = cursor.getString(0); String date = cursor.getString(1); updateUi(note, date);} finally { cursor.close();}
  • 7. greenDAO Overview Entities & DAOs Code generation Open Source: https://github.com/greenrobot/greenDAO Apache 2 license: core library (embedded in your app) GPL3: generator (you usually don‘t have changes here)
  • 8. greenDAO StructureGenerator Project Android Project (Plain Java) Sources Schema-Model • Entities • Properties Generated • Relations Sources greenDAO Code Generation • Indexes, … • Entities • DAOs greenDAO Generator Lib greenDAO +FreeMarker Core Lib
  • 9. Code Generation: Meta Model In generator project Defines data model (your schema) Define with Java
  • 10. Example: Model for GeneratorSchema schema = new Schema(1, "de.greenrobot.daoexample");Entity simple = schema.addEntity("Note");simple.addIdProperty();simple.addStringProperty("text").notNull();simple.addDateProperty("date");new DaoGenerator().generateAll( "../DaoExample/src-gen", schema);
  • 11. Example: Generated Entitypublic class Note { private String text; // ID, date and constructors skipped public String getText() { return text; } public void setText(String text) { this.text = text; }}
  • 12. Code: Insert, Update, DeleteNote note = new Note();note.setText(“Say hello to world”);noteDao.insert(note);Log.d("Dao", “New ID: " + note.getId());note.setText(“Save the world”);noteDao.update(note);noteDao.delete(note);
  • 13. QueryBuilder References generated Properties Java Complier checks Example: Get all users with first name “Joe“, and sort by last name List<User> joes = userDao.queryBuilder() .where(Properties.FirstName.eq("Joe")) .orderAsc(Properties.LastName) .list();
  • 14. Entity relations Entity type relates to another entity type Supports to-one and to-many relations Unidirectional Bidirectional: requires manual updates
  • 15. ToOne Example Entities Customer & Order An order has one customer Modelling in the generator project Property customerId = order.addLongProperty( "customerId").notNull().getProperty(); order.addToOne(customer, customerId); Resolving in the app Customer customer = order.getCostumer();
  • 16. ToMany Example Entities Customer & Order A customer places many orders Modelling in the generator project Property customerId = order.addLongProperty( "customerId").notNull().getProperty(); customer.addToMany(order, customerId); Resolving in the app List<Order> orders = costumer.getOrderList();
  • 17. Active Entities Have (some) persistence methods – update – delete – refresh
  • 18. greenDAO Design Goals Maximum Performance Low resource usage – Memory consumption – Library size Easy-to-use API Focus on the essentials Optimized for Android
  • 19. Save size, keep it the DRY way Generate code, but as sparly as possible Example: load method of DAO AbstractDao class (core library) – Implements everything expect readEntity Generated DAO implements readEntity – Just construct entities from a cursor position Library size: 59 KByte + some K per DAO
  • 20. 3 Basic Performance Rules1. Group DB changes into a transaction! Can be like 500 times faster; still a FAQ2. Don’t forget database indexes3. Use prepared statements (precompiled)
  • 21. Regular Performance Tracking Different scenarios are tested Tracked in Excel files Excel files are pushed to github
  • 22. Why Code Generation? Annotation-based solutions: common with JEE ORMs (Hibernate, JPA) Parsing of annotations  start-up time Android & annotations: getting/setting values requires reflection Reflection quite slow on Android (n. slide) Code generation to avoid reflection
  • 23. Reflection PerformanceMethod Reflection (roughly)getInt ~ 50 x slowergetString ~ 50 x slowersetInt ~ 400 x slowersetString ~ 150 x slower Example: 100,000 Operations (e.g. 10,000 entities with 10 properties) setInt: 9 ms, reflected 3875ms
  • 24. Profiling to find hotspots Use traceview Enable in code: Debug. startMethodTracing( traceName); See class PerformanceTest
  • 25. Reading entities & Constructor Entities read from the database Solution 1: Calling setters MyEntity myEntity = new MyEntity(); myEntity.setX(cursor.getString(0)); … Solution 2: Constructor only MyEntity myEntity = new MyEntity( cursor.getString(0), …); Performance gain: 33%
  • 26. Optimization Candidate: Cursor Quite some time is spent in Android API android.database.AbstractWindowedCursor get… Methods are “slow” @Override public short getShort(int columnIndex) { checkPosition(); return mWindow.getShort(mPos, columnIndex); } @Override public int getInt(int columnIndex) { checkPosition(); return mWindow.getInt(mPos, columnIndex); }
  • 27. Custom Cursor implementation Replacing SQLiteCursor de.greenrobot.dao.FastCursor Performance gain: ~30%
  • 28. Lookup by ID Identity Scope (≈ Entity Caching) Mapping ID  Entity HashMap<Long, MyEntity> Problem: Long object creation LongSparseArray<MyEntity> Problem: does not scale Evaluated several alternatives
  • 29. LongHashMap & More Custom de.greenrobot.dao.LongHashMap + Locking improvements + Minor performance tweaks Performance gain: from 30% up to 117%
  • 30. Performance: Entities / SecondMeasured on a Nexus S (1 GHz), Android 2.3
  • 31. Performance comparisonMeasured on a Nexus S (1 GHz), Android 2.3
  • 32. Current Workflow vs. Migration Works best if you start from scratch (Start with Entity modeling) Migration: additional effort required – Pre-existing entities: have to be replaced – Existing tables: entities have to modeled Ideas how to address migration – Generic DAO (Annotation based entities!) – Import existing Model from SQLite DB files
  • 33. Current Feature Requests Generate Adapters, CRUD Apps, Parceable, conversion to JSON/XML, … Convenience support for async ops Client/Server(Cloud) data synchronization More flexible primary keys (PKs) Pre- and post persist callbacks What is most important to you?
  • 34. Disclaimer, Rechtliches Alle Inhalte urheberrechtlich geschützt. © Copyright 2011 Markus Junginger All rights reserved. Kontakt: markus@greenrobot.de http://greenrobot.de http://twitter.com/#!/greenrobot_de