Strategy 7 (Android): by Nicolas Diaz Montaña - ISIS3510-MOBILE-T34/T34-Wiki-SpendiQ GitHub Wiki

Micro-Optimization Strategy in the New TransactionViewModel Model

Strategy Description

This strategy focuses on improving the efficiency of transaction handling in the application by implementing a more robust caching system and utilizing iterators for data processing. Compared to the previous model, the new model optimizes memory usage and computational efficiency by avoiding unnecessary operations and handling data more effectively.


Micro-Optimization Implementation

Step 1: Using Iterators to Process Transactions

In the new model, iterators (TransactionIterator and MonthlyTransactionIterator) are used to handle transactions. This enables more efficient data processing, as iterators allow controlled and optimized traversal of collections.

Example Before Optimization

val transactions = transactionRepository.getAllTransactions()
val filteredTransactions = transactions.filter { it.type == TransactionType.EXPENSE }

Example After Optimization

val filteredTransactions = transactionRepository.getAllTransactions()
    .asSequence()
    .filter { it.type == TransactionType.EXPENSE }

Explanation

  • Iterators vs. Lists: Iterators provide more efficient access to collection elements, particularly for large datasets. This reduces memory overhead and improves performance by avoiding unnecessary copies of lists.

Step 2: Implementing an Enhanced Caching System

The new model incorporates a caching system (MovementsCache) that enables efficient storage and retrieval of data. This is particularly beneficial for handling data that does not change frequently, such as monthly income and expenses.

Example of Cache Usage

class MovementsCache {
    private val cache = mutableMapOf<String, List<Transaction>>()

    fun getCachedData(key: String): List<Transaction>? = cache[key]

    fun cacheData(key: String, data: List<Transaction>) {
        cache[key] = data
    }
}

Performance Evaluation

Before Implementation

image

After Implementation

image

Metrics: Memory Usage and CPU Usage

The evaluation focuses on two key performance metrics:

  1. Memory Usage: Measured in kilobytes (KB), comparing the application's memory footprint before and after optimization.
  2. CPU Usage: Observed in the profiler to assess the reduction in CPU peaks during operation, ensuring smoother processing.

Results

Memory Usage

Metric Before Optimization After Optimization Improvement
Average Memory Usage (KB) 15.5 MB 14.2 MB 1.3 MB (8.39%)

CPU Usage

Metric Before Optimization After Optimization Improvement
Peak CPU Usage High spikes visible Smooth with fewer peaks Reduced overhead from repeated calls

Explanation

Memory Savings

  • Iterators: Avoid creation of temporary lists, reducing memory allocation and deallocation costs.
  • Caching: Minimizes repeated database or network calls, further decreasing memory consumption.

CPU Efficiency

  • Reduced Peaks: The use of caching lowers computational overhead, as data retrieval operations become less resource-intensive.
  • Iterators: Efficient traversal mechanisms eliminate redundant processing, contributing to smoother CPU activity.

Conclusions

The optimizations in the TransactionViewModel model have led to measurable improvements in both memory and CPU usage:

  • Memory Usage: Reduced by 8.39%, ensuring a lighter application footprint.
  • CPU Performance: Noticeable reduction in peaks as seen in the profiler, indicating more efficient data handling and processing.

These improvements not only enhance the technical performance of the application but also deliver a smoother and more responsive user experience, critical for mobile applications where resources are constrained.