Android Performance

Performance Considerations in Operating System Design

Word count: 1.7kReading time: 10 min
2023/08/21
loading

[!NOTE]
This article was originally written by Yingyun for my Knowledge Planet. Since the Planet has closed, I am publishing this series on OS performance design here.

Yingyun is a veteran performance optimization expert with deep insights into system-level tuning, having worked at several major smartphone manufacturers. He is currently active in our community. If you have any questions or feedback, feel free to join our WeChat group.

1. The Genesis

This starts a new series exploring the various considerations in OS architectural design. In reality, these principles apply to the design of any large-scale software.

These views are my own and carry a subjective perspective. I welcome different viewpoints and hope that through their collision, we can all reach a deeper understanding of the field.

From an OS perspective, I believe the core differences between Android and iOS manifest in four areas:

  1. IPC Mechanisms between applications and core services.
  2. Platform Development Environment: programming languages, IDEs, and developer ecosystems.
  3. Application Lifecycle Management: mechanisms and strategies.
  4. Runtime Organization of the kernel and core services.

Why did they make such different strategic decisions? It all boils to the constraints and goals present during their architectural infancy. A software architecture is a collection of decisions made to be the most “correct” for the present and foreseeable future. There is no absolute right or wrong—only choices made under different pressures. If you swapped the contexts of two equally skilled architects, they would likely end up with very similar designs. Architecture is an engineering craft; it follows predictable patterns.

The challenge lies in accurately understanding the organization’s environment and anticipating which factors—testability, release efficiency, security, reliability, performance, or scalability—must be prioritized. An experienced architect knows when to be rigid and when to compromise. Because of the law of diminishing marginal utility, these trade-offs continue throughout the software’s entire lifecycle.

Key takeaways:

  1. Software architecture design varies across different projects based on phase and constraints.
  2. Design decisions are fluid and happen continuously throughout the product lifecycle.

Interestingly, optimization goals often conflict. For example, increasing developer efficiency often comes at the cost of runtime performance. What were the priorities for the original designers of Android and iOS? To answer that, we must first define the relationship between the OS, the application, and the kernel.

2. Mechanism vs. Strategy

An Operating System is part of the software stack built on top of hardware. Together with applications, it forms the complete software environment that leverages hardware to serve the user.

From the hardware’s perspective, both the OS and the app are just software. The OS just has higher privileges (CPU supervisor mode) to interact directly with hardware or handle interrupts. From a developer’s perspective, however, they are worlds apart. The app uses the OS’s capabilities to fulfill business logic or access hardware (e.g., playing audio, storing data).

From a user experience (UX) perspective, the hardware, OS, and app are a single entity. If they fail to collaborate, the device feels broken. All three have an obligation to cooperate to satisfy the consumer.

Most modern OSs consist of a Kernel and System Services:

  • macOS/iOS: The kernel is Darwin (comprising XNU and MACH microkernels). System services are a collection of daemons providing APIs for data management, UI, etc.
  • Android: The kernel is Linux. System services include C++ daemons (like SurfaceFlinger) and Java daemons (like SystemServer), providing APIs for rendering, resource management, etc.

While many OSs use similar foundations, the way they are deployed matters. Running an OS is not the same as running it well.

A classic OS design principle is the separation of Mechanism and Strategy:

  • Mechanism: Provides the capability (the “How”).
  • Strategy: Decides how to use that capability (the “What”).

In Linux, memory management, process management, and VFS are mechanisms. The specific memory allocator, the process scheduler, and the specific filesystem are strategies.

Furthermore, a system service identifying which processes are user-facing vs. background tasks and syncing that to the scheduler is a strategy built on top of the process management mechanism. Similarly, Dynamic Voltage and Frequency Scaling (DVFS) is a strategy for hardware power management mechanisms.

Mechanisms might be similar across OSs, but strategies vary wildly. This depends on the designer’s understanding of the target service. Early Android followed a desktop-like architecture. Over years of “aggressive” modification by Chinese manufacturers, it has become more iOS-like—aligning better with what a mobile device actually needs.

3. Perspective Decisions

Apple’s OSs (macOS, iOS, watchOS, etc.) share underlying mechanisms but have radically different strategies. iOS uses a “restricted multitasking” strategy for power/performance reasons, while macOS is true multitasking. This wasn’t a technical limitation for iOS; it was a deliberate design choice.

Android is an open-source project (AOSP). Manufacturers take AOSP, add hardware-specific code and their own services. Since manufacturers have different business models and user bases, they modify AOSP differently. The market ultimately judges which modification is superior.

Technically, AOSP provides many mechanisms but lacks cohesive “consumer” strategies. Google implements those strategies in its proprietary GMS (Google Mobile Services). Manufacturers (especially in China) have filled this “strategy gap” by tailoring AOSP to local consumer needs.

The Origin Story

In Becoming Steve Jobs, it’s noted that Jobs initially opposed third-party apps on the iPhone due to power and security concerns. He wanted a device with a “perfect” user experience. He preferred a closed system where Apple controlled every variable to ensure elegance. Because the iPhone used a macOS kernel (XNU), which is resource-heavy, letting third-party code run freely on 2007 hardware was unthinkable.

Eventually, the VP team convinced him that the success of the iTunes + App Store model was too great to ignore. Even then, Apple built its own OS, its own IDE (Xcode), and its own store to define what a “best app” should look like.

Contrast this with Android. Andy Rubin’s goal was a truly open system to balance the interests of developers, manufacturers, and carriers. This required using off-the-shelf components to deploy quickly. There was no time for the same level of polishing because they were in a race for survival.

Android chose Java because it was the most popular language at the time. While Java’s overhead was high for 2007 mobile hardware, it offered portability and a massive developer pool. To make it work, they built a specialized VM (Dalvik/ART). Luckily, Android hit the “golden decade” of exploding mobile CPU performance, which helped it hide its architectural weight compared to iOS.

The Power of the IDE

Apple’s dominance in its ecosystem is largely due to Xcode. It integrates performance analysis, debugging, and distribution so seamlessly that developers can find bottlenecks with minimal learning. LLVM, Swift, and SwiftUI are all tools designed to help developers write software that fits the system’s needs perfectly.

Designing an OS is a means to an end (profit). To achieve that, you must help developers write good code. Many OSs provide the capability but leave the quality to the developer. Apple’s approach is: “I’ll give you limits, but I’ll also give you the solution to work within them.”

4. Strategy: Overload Protection

The biggest constraint of mobile devices is the battery and passive cooling. As transistor density nears physical limits and we pack more features into chips, heat is the enemy.

Mobile OS design naturally necessitates resource limits. Unlike servers, you cannot just let an app run wild. The more constrained the device (like a smartwatch), the stricter the limits.

  • Android: Primarily uses OOM (Out of Memory) management. It has some basic CPU detection for Java threads, but it’s relatively primitive.
  • iOS: Has a massive suite of protections. An app is terminated if:
    • The device overheats.
    • VoIP apps wake the CPU too often.
    • BackgroundTask time/CPU usage exceeds thresholds.
    • Disk I/O writes exceed limits.
    • Memory usage spikes.
    • The system suffers from “PageCache Thrashing.”

Google’s “looser” design left room for manufacturers to innovate. However, because these manufacturer-specific “kill” strategies aren’t always documented, developers often resort to “black magic” (keep-alive tricks) to stay running. This leads to a cat-and-mouse game where the user loses.

5. Strategy: Lifecycle Management

In desktop OSs, an app’s lifecycle is controlled by the app itself. The OS tries to give it as much power as possible.

On mobile, the OS decides who lives and dies. Android’s design was initially “loose” (desktop-like). iOS was “strict”—apps entering the background have about 5 seconds to finish work before being suspended.

Manufacturers have implemented “suspension” or “freezing” mechanisms in AOSP, but because they aren’t native core mechanisms, they are often inconsistent. If an app is suspended in iOS, how does it do background work? It uses BackgroundTask APIs. The OS controls when the work happens based on system load and power levels.

This requires a centralized control point, which for Apple is the App Store. It validates that an app’s requested background permissions match its functionality. Without a unified store or GMS in some regions, the Android ecosystem has become “disfigured,” with apps using aggressive tactics to stay alive just to receive notifications.

6. Designing for the Future

The history of electronics is a move toward specialized hardware replacing general CPU tasks (DSA - Domain Specific Architecture). As we hit the end of the “CPU performance dividend,” the next decade belongs to specialized silicon, compilers, and architectures.

Apple’s M1 is the perfect example. It’s not just a faster CPU; it’s a collection of specialized engines (video, media, neural) that outperform general-purpose chips by a massive margin in specific scenarios.

To provide a premium experience, you need an Optimization Matrix: the OS, the IDE, cloud coordination, and specialized hardware working together. It’s no longer just about the code; it’s about the entire loop.


About Me && Blog

(Links and introduction)

CATALOG
  1. 1. 1. The Genesis
  2. 2. 2. Mechanism vs. Strategy
  3. 3. 3. Perspective Decisions
    1. 3.0.1. The Origin Story
    2. 3.0.2. The Power of the IDE
  • 4. 4. Strategy: Overload Protection
  • 5. 5. Strategy: Lifecycle Management
  • 6. 6. Designing for the Future
  • 7. About Me && Blog