SlideShare a Scribd company logo
1 of 10
Download to read offline
Performance & Memory Tuning - Part II
We'll start with common strategies and performance pitfalls. This list is by no means exhaustive but it represents a lot of the experience we've had over the years.
Don't Block the EDT
© Codename One 2017 all rights reserved
✦#1 performance tip!
✦EDT = Event Dispatch Thread
✦EDT Cycle must complete well below 16ms
✦Doing lengthy things on the EDT can kill performance
✦Use threads and NetworkManager
Don’t block the EDT. This is the #1 performance tip. If you have one takeaway from this it should be this statement.

The Event Dispatch Thread (EDT) is the thread that is invoked for every listener, event or paint operation. It does everything in Codename One. 

The EDT runs a cycle that's supposed to finish well below the 16 milliseconds mark. That's important because the EDT is only one part and after it is done the native
thread needs to perform some work as well.

If you perform lengthly operations on the EDT such as parsing you might see a performance penalty. To be fair we do these things too. A lot of our demos perform some
parsing and image loading on the EDT. Most API's must be invoked on the EDT which makes it hard to avoid blocking it.

The core workaround for this penalty is to delegate work into another thread. We can do this with the NetworkManager which implicitly uses the network thread for
communication. You can also open a thread to do intensive work and return to the EDT with a callSerially invocation.
label.setText("Loading, please wait...");
startThread(() -> {
performSlowCode();
callSerially(() -> label.setText("Finished!"));
}, "Loading Thread").start();
Delegate EDT to Thread
A simple example of this would be something like this we launch a separate thread to run slow code and then return the response to the EDT with callSerially
label.setText("Loading, please wait...");
invokeAndBlock(() -> {
performSlowCode();
});
label.setText("Finished!");
invokeAndBlock
One approach to offload processing is invokeAndBlock which spawns a thread while blocking the EDT in a non-disruptive way. This makes development very convenient
as you can avoid nested callbacks.

However, `invokeAndBlock` is more expensive in terms of performance than a regular thread & callback approach. So if you are concerned about performance
invokeAndBlock might not be the best option.

These concerns should also apply to the addToQueueAndWait method from the NetworkManager which would also incur a similar cost.
callSeriallyOnIdle(() -> addShadowToComponent());
callSeriallyOnIdle
One of the tricks I did in the Uber application for features such as shadow was leverage the callSeriallyOnIdle method. This method works like callSerially but it invokes
the code only when the EDT is idle. 

Idle state happens when the EDT is ready to sleep and doesn't have too much to do. Initially I rendered the component without a shadow and added the shadow after
the fact using a call like this.
Threads aren't Magic
© Codename One 2017 all rights reserved
✦Threads aren’t enough
✦A separate thread can starve the EDT
✦The EDT itself contains some sleep code
✦Your custom threads need to yield too
✦There is a special exception for IO
✦If you have long calculations you need to sleep in the
code occasionally
✦Synchronization can erase the value of a thread
Threads aren’t magic. This is somewhat contradictory to the recent statements but threads aren't enough. Developers often perform a slow operation on a thread only to
discover that rendering is seriously impacted.

Mobile CPU's aren't as fast as people think and they are bad at task switching. If you spawn a thread that takes too long and uses a lot of CPU resources it will "starve"
the EDT and potentially cause rendering to be sluggish as a result.

In fact we force the EDT to sleep with every cycle so it won't starve the native rendering thread!

The solution is to explicitly yield the thread occasionally if you don't do IO.

Notice that if you are reading or writing to a stream the underlying kernel stream reading code should yield the CPU for you

Assuming you have a long calculation you can just sprinkle Util.sleep(1) or even longer through the thread code to make sure the CPU delegates time to other threads

While we are on this subject I’d like to say a couple of things about thread safety. Creating threads is important but performant synchronization is often challenging and
error prone. It might negatively impact the performance benefit deliver from threads to begin with.

One of the advantages of the single thread approach in the EDT is that we can avoid synchronization almost entirely within the Codename One code. This reduces
overhead noticeably as synchronization is a very expensive operation that can't be optimized by compiler and even impacts JITs.

If you need to use a thread I would recommend the EasyThread class which simplifies the process of communicating with the EDT in a way similar to callSerially.
Image img = createImage(...);
Label imageLabel = new Label(img);
Caching Strategies
Caching is at the core of almost every optimization you will make. Caching can be as simple as keeping a value in a variable or as complex as weak references with
purge strategies.

A core decision about caching is where to cache and what to cache. Lets say I have this code… Should we cache the image or should we cache the label?

There is no simple answer. Normally I wouldn't cache the Label preferring to cache the Form but the logic of Image caching is tricky...

If I keep an image and then create a scaled version of that image I'll effectively have 2 instances of that image in RAM. The only tip I can give about this is awareness.
Look at the things you cache and try to avoid caching in the wrong place.

Notice that a 2gb RAM device doesn't allocate that RAM to the application. The application gets far less and this should be further restricted as device OS's kill
applications that take up too much RAM
Form Reuse vs. Allocation
© Codename One 2017 all rights reserved
✦We used to recommend Form discard but today we
recommend instance reuse
✦Recreating the Form is harder and potentially slower
✦Todays devices have more RAM and caching forms
should be fine for most cases
That brings up a common question, should we reuse Form instances?

In the past we used to recommend that developers discard Form instances once they were done with them. Then if they needed to go back to the Form they could
create a new instance. This was the strategy in the old Codename One GUI builder and it has an advantage in terms of RAM usage.

However, it makes some things very hard to code (going back to the exact previous state of the Form) and it is arguably slower in terms of performance. Today for the
most part we advocate the reuse of Form instances (but not dialogs which are more transient by nature).

The logic behind reuse relates to the amount of RAM available on the devices and taken up by a Form. It should be OK for the most part. The problems start with forms
that contain many images. In those cases we need a strategy to purge memory when leaving the Form.
// save object to cache
myObjectCache = createSoftWeakRef(objectToCache);
// extract object from cache
Object hardRef = extractHardRef(myObjectCache);
if(hardRef != null) {
// data wasn't gc'd
}
Weak/Soft References
There are some elements that might be expensive to cache such as images. In these cases we want to cache the data for the performance benefit but if we don't have
enough RAM we'd rather discard it.

This is in fact the strategy taken by EncodedImage which I'll discuss later.

Java SE has builtin classes that cover a lot of the details such as WeakReference/SoftReference etc. Unfortunately soft references which are the more useful option aren't
available. The solution is available in the CN class. 

Java SE also offers WeakHashMap which we refactored into com.codename1.ui.util. It uses the soft references builtin to Codename One. This class is essentially a
regular Map that can lose its value objects when memory gets low.
CacheMap
© Codename One 2017 all rights reserved
✦Cache Map fallbacks to storage too
✦Meant for network data
✦For simple stuff Preferences is probably better
Another common class for caching is the CacheMap unlike the WeakHashMap it caches data and saves extra data to storage. 

So it's meant to cache data that you might fetch from the network or a similar source.

It makes sense for larger elements for small cached data I would just use Preferences.

More Related Content

Similar to Performance and Memory Tuning - Part II - Transcript.pdf

C++ Restrictions for Game Programming.
C++ Restrictions for Game Programming.C++ Restrictions for Game Programming.
C++ Restrictions for Game Programming.Richard Taylor
 
node.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoonnode.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang YoonJesang Yoon
 
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...Jason Hearne-McGuiness
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
PHP Mega Meetup, Sep, 2020, Anti patterns in php
PHP Mega Meetup, Sep, 2020, Anti patterns in phpPHP Mega Meetup, Sep, 2020, Anti patterns in php
PHP Mega Meetup, Sep, 2020, Anti patterns in phpAhmed Abdou
 
CDI debugger for embedded C/C+
CDI debugger for embedded C/C+CDI debugger for embedded C/C+
CDI debugger for embedded C/C+Teodor Madan
 
2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with BlackfireMarko Mitranić
 
Performant Django - Ara Anjargolian
Performant Django - Ara AnjargolianPerformant Django - Ara Anjargolian
Performant Django - Ara AnjargolianHakka Labs
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroSteven Pignataro
 
PyCon Canada 2019 - Introduction to Asynchronous Programming
PyCon Canada 2019 - Introduction to Asynchronous ProgrammingPyCon Canada 2019 - Introduction to Asynchronous Programming
PyCon Canada 2019 - Introduction to Asynchronous ProgrammingJuti Noppornpitak
 
2012 04-19 theory-of_operation
2012 04-19 theory-of_operation2012 04-19 theory-of_operation
2012 04-19 theory-of_operationbobwolff68
 
How do I - Storage, FileSystem & SQL - Transcript.pdf
How do I - Storage, FileSystem & SQL - Transcript.pdfHow do I - Storage, FileSystem & SQL - Transcript.pdf
How do I - Storage, FileSystem & SQL - Transcript.pdfShaiAlmog1
 
Mobile Developer Summit 2012, Pune
Mobile Developer Summit 2012, PuneMobile Developer Summit 2012, Pune
Mobile Developer Summit 2012, PuneBhuvan Khanna
 
Caching & Performance In Cold Fusion
Caching & Performance In Cold FusionCaching & Performance In Cold Fusion
Caching & Performance In Cold FusionDenard Springle IV
 
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJava Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJAX London
 
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedJoão Pedro Martins
 
Front-End Modernization for Mortals
Front-End Modernization for MortalsFront-End Modernization for Mortals
Front-End Modernization for Mortalscgack
 
Front end-modernization
Front end-modernizationFront end-modernization
Front end-modernizationdevObjective
 

Similar to Performance and Memory Tuning - Part II - Transcript.pdf (20)

C++ Restrictions for Game Programming.
C++ Restrictions for Game Programming.C++ Restrictions for Game Programming.
C++ Restrictions for Game Programming.
 
node.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoonnode.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoon
 
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
PHP Mega Meetup, Sep, 2020, Anti patterns in php
PHP Mega Meetup, Sep, 2020, Anti patterns in phpPHP Mega Meetup, Sep, 2020, Anti patterns in php
PHP Mega Meetup, Sep, 2020, Anti patterns in php
 
CDI debugger for embedded C/C+
CDI debugger for embedded C/C+CDI debugger for embedded C/C+
CDI debugger for embedded C/C+
 
2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire2019 StartIT - Boosting your performance with Blackfire
2019 StartIT - Boosting your performance with Blackfire
 
Performant Django - Ara Anjargolian
Performant Django - Ara AnjargolianPerformant Django - Ara Anjargolian
Performant Django - Ara Anjargolian
 
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven PignataroJoomla! Day Chicago 2011 Presentation - Steven Pignataro
Joomla! Day Chicago 2011 Presentation - Steven Pignataro
 
PyCon Canada 2019 - Introduction to Asynchronous Programming
PyCon Canada 2019 - Introduction to Asynchronous ProgrammingPyCon Canada 2019 - Introduction to Asynchronous Programming
PyCon Canada 2019 - Introduction to Asynchronous Programming
 
2012 04-19 theory-of_operation
2012 04-19 theory-of_operation2012 04-19 theory-of_operation
2012 04-19 theory-of_operation
 
How do I - Storage, FileSystem & SQL - Transcript.pdf
How do I - Storage, FileSystem & SQL - Transcript.pdfHow do I - Storage, FileSystem & SQL - Transcript.pdf
How do I - Storage, FileSystem & SQL - Transcript.pdf
 
Java Threading
Java ThreadingJava Threading
Java Threading
 
Mobile Developer Summit 2012, Pune
Mobile Developer Summit 2012, PuneMobile Developer Summit 2012, Pune
Mobile Developer Summit 2012, Pune
 
Spark rdd
Spark rddSpark rdd
Spark rdd
 
Caching & Performance In Cold Fusion
Caching & Performance In Cold FusionCaching & Performance In Cold Fusion
Caching & Performance In Cold Fusion
 
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJava Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
 
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons LearnedITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
ITARC15 Workshop - Architecting a Large Software Project - Lessons Learned
 
Front-End Modernization for Mortals
Front-End Modernization for MortalsFront-End Modernization for Mortals
Front-End Modernization for Mortals
 
Front end-modernization
Front end-modernizationFront end-modernization
Front end-modernization
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 

Recently uploaded

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Recently uploaded (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 

Performance and Memory Tuning - Part II - Transcript.pdf

  • 1. Performance & Memory Tuning - Part II We'll start with common strategies and performance pitfalls. This list is by no means exhaustive but it represents a lot of the experience we've had over the years.
  • 2. Don't Block the EDT © Codename One 2017 all rights reserved ✦#1 performance tip! ✦EDT = Event Dispatch Thread ✦EDT Cycle must complete well below 16ms ✦Doing lengthy things on the EDT can kill performance ✦Use threads and NetworkManager Don’t block the EDT. This is the #1 performance tip. If you have one takeaway from this it should be this statement. The Event Dispatch Thread (EDT) is the thread that is invoked for every listener, event or paint operation. It does everything in Codename One. The EDT runs a cycle that's supposed to finish well below the 16 milliseconds mark. That's important because the EDT is only one part and after it is done the native thread needs to perform some work as well. If you perform lengthly operations on the EDT such as parsing you might see a performance penalty. To be fair we do these things too. A lot of our demos perform some parsing and image loading on the EDT. Most API's must be invoked on the EDT which makes it hard to avoid blocking it. The core workaround for this penalty is to delegate work into another thread. We can do this with the NetworkManager which implicitly uses the network thread for communication. You can also open a thread to do intensive work and return to the EDT with a callSerially invocation.
  • 3. label.setText("Loading, please wait..."); startThread(() -> { performSlowCode(); callSerially(() -> label.setText("Finished!")); }, "Loading Thread").start(); Delegate EDT to Thread A simple example of this would be something like this we launch a separate thread to run slow code and then return the response to the EDT with callSerially
  • 4. label.setText("Loading, please wait..."); invokeAndBlock(() -> { performSlowCode(); }); label.setText("Finished!"); invokeAndBlock One approach to offload processing is invokeAndBlock which spawns a thread while blocking the EDT in a non-disruptive way. This makes development very convenient as you can avoid nested callbacks. However, `invokeAndBlock` is more expensive in terms of performance than a regular thread & callback approach. So if you are concerned about performance invokeAndBlock might not be the best option. These concerns should also apply to the addToQueueAndWait method from the NetworkManager which would also incur a similar cost.
  • 5. callSeriallyOnIdle(() -> addShadowToComponent()); callSeriallyOnIdle One of the tricks I did in the Uber application for features such as shadow was leverage the callSeriallyOnIdle method. This method works like callSerially but it invokes the code only when the EDT is idle. Idle state happens when the EDT is ready to sleep and doesn't have too much to do. Initially I rendered the component without a shadow and added the shadow after the fact using a call like this.
  • 6. Threads aren't Magic © Codename One 2017 all rights reserved ✦Threads aren’t enough ✦A separate thread can starve the EDT ✦The EDT itself contains some sleep code ✦Your custom threads need to yield too ✦There is a special exception for IO ✦If you have long calculations you need to sleep in the code occasionally ✦Synchronization can erase the value of a thread Threads aren’t magic. This is somewhat contradictory to the recent statements but threads aren't enough. Developers often perform a slow operation on a thread only to discover that rendering is seriously impacted. Mobile CPU's aren't as fast as people think and they are bad at task switching. If you spawn a thread that takes too long and uses a lot of CPU resources it will "starve" the EDT and potentially cause rendering to be sluggish as a result. In fact we force the EDT to sleep with every cycle so it won't starve the native rendering thread! The solution is to explicitly yield the thread occasionally if you don't do IO. Notice that if you are reading or writing to a stream the underlying kernel stream reading code should yield the CPU for you Assuming you have a long calculation you can just sprinkle Util.sleep(1) or even longer through the thread code to make sure the CPU delegates time to other threads While we are on this subject I’d like to say a couple of things about thread safety. Creating threads is important but performant synchronization is often challenging and error prone. It might negatively impact the performance benefit deliver from threads to begin with. One of the advantages of the single thread approach in the EDT is that we can avoid synchronization almost entirely within the Codename One code. This reduces overhead noticeably as synchronization is a very expensive operation that can't be optimized by compiler and even impacts JITs. If you need to use a thread I would recommend the EasyThread class which simplifies the process of communicating with the EDT in a way similar to callSerially.
  • 7. Image img = createImage(...); Label imageLabel = new Label(img); Caching Strategies Caching is at the core of almost every optimization you will make. Caching can be as simple as keeping a value in a variable or as complex as weak references with purge strategies. A core decision about caching is where to cache and what to cache. Lets say I have this code… Should we cache the image or should we cache the label? There is no simple answer. Normally I wouldn't cache the Label preferring to cache the Form but the logic of Image caching is tricky... If I keep an image and then create a scaled version of that image I'll effectively have 2 instances of that image in RAM. The only tip I can give about this is awareness. Look at the things you cache and try to avoid caching in the wrong place. Notice that a 2gb RAM device doesn't allocate that RAM to the application. The application gets far less and this should be further restricted as device OS's kill applications that take up too much RAM
  • 8. Form Reuse vs. Allocation © Codename One 2017 all rights reserved ✦We used to recommend Form discard but today we recommend instance reuse ✦Recreating the Form is harder and potentially slower ✦Todays devices have more RAM and caching forms should be fine for most cases That brings up a common question, should we reuse Form instances? In the past we used to recommend that developers discard Form instances once they were done with them. Then if they needed to go back to the Form they could create a new instance. This was the strategy in the old Codename One GUI builder and it has an advantage in terms of RAM usage. However, it makes some things very hard to code (going back to the exact previous state of the Form) and it is arguably slower in terms of performance. Today for the most part we advocate the reuse of Form instances (but not dialogs which are more transient by nature). The logic behind reuse relates to the amount of RAM available on the devices and taken up by a Form. It should be OK for the most part. The problems start with forms that contain many images. In those cases we need a strategy to purge memory when leaving the Form.
  • 9. // save object to cache myObjectCache = createSoftWeakRef(objectToCache); // extract object from cache Object hardRef = extractHardRef(myObjectCache); if(hardRef != null) { // data wasn't gc'd } Weak/Soft References There are some elements that might be expensive to cache such as images. In these cases we want to cache the data for the performance benefit but if we don't have enough RAM we'd rather discard it. This is in fact the strategy taken by EncodedImage which I'll discuss later. Java SE has builtin classes that cover a lot of the details such as WeakReference/SoftReference etc. Unfortunately soft references which are the more useful option aren't available. The solution is available in the CN class. Java SE also offers WeakHashMap which we refactored into com.codename1.ui.util. It uses the soft references builtin to Codename One. This class is essentially a regular Map that can lose its value objects when memory gets low.
  • 10. CacheMap © Codename One 2017 all rights reserved ✦Cache Map fallbacks to storage too ✦Meant for network data ✦For simple stuff Preferences is probably better Another common class for caching is the CacheMap unlike the WeakHashMap it caches data and saves extra data to storage. So it's meant to cache data that you might fetch from the network or a similar source. It makes sense for larger elements for small cached data I would just use Preferences.