🧵 Fast and easy multithreading for React Native using JSI

Overview

react-native-multithreading

🧵 Fast and easy multithreading for React Native using JSI.


Buy Me a Coffee at ko-fi.com


Installation

npm install react-native-multithreading
npx pod-install

Requires a version of react-native-reanimated which includes PR #1790. Either patch it yourself, or wait until that lands in a release.

⚠️ Warning: This is still just a proof of concept - do not use this library in production! ⚠️

Why

Since JSI is becoming more mainstream, there might be functions that are actually blocking and take a while to execute. For example, a storage library like my react-native-mmkv or an SQLite JSI library might take a few milliseconds to execute a complex call. You don't want your entire React-JS thread to freeze when doing that, since users will perceive a noticeable lag or freeze.

That's where react-native-multithreading comes in; you can simply off-load such expensive calculations/blocking calls to a separate thread with almost no overhead while your main React-JS thread can concentrate on running your app's business logic, respond to user input, update state and more. You can also run complex JS calculations such as the Fibonacci number, but that's probably a rare use-case.

Inspired by @karol-bisztyga's Multithreading PR for Reanimated

Usage

To try out the Fibonacci Example, clone the repo and run the following commands:

yarn bootstrap
cd example
yarn ios

See my tweet 🐦

Shoot and Forget

To simply perform an expensive calculation on another thread without caring about the result, use the spawnThread function:

// JS thread
spawnThread(() => {
  'worklet'
  // custom thread
  // expensive calculation
})
// JS thread

The React-JS Thread will continue execution while the custom thread will run the given function on a custom parallel runtime.

Await

Since spawnThread returns a Promise, you can also await the result. The React-JS Thread will not be blocked and will still be able to continue execution elsewhere (timers, callbacks, ...), while the custom thread runs the given function in a custom parallel runtime.

const result = await spawnThread(() => {
  'worklet'
  // expensive calculation
  return ...
})

Fibonacci

This example calculates the Fibonacci Number for the given input. This demonstrates expensive calculation, awaiting the result, as well as using values from "outside". (fibonacci function and input are captured into the new thread and therefore immutable.)

const fibonacci = (num: number): number => {
  'worklet'
  if (num <= 1) return 1
  return fibonacci(num - 1) + fibonacci(num - 2)
}

const input = 50
const result = await spawnThread(() => {
  'worklet'
  console.log(`calculating fibonacci for input: ${input} in JS-Runtime: ${global._LABEL}...`)
  const fib = fibonacci(input)
  console.log("finished calculating fibonacci!")
  return fib
})
console.log(`Fibonacci Result: ${result}`)

What's possible?

  • You can use variables from "outside" (e.g. state), but those will be immutable/frozen.
  • You can use functions from "outside" if they also contain the 'worklet' directive.
  • You can assign Reanimated Shared Values.
  • You can call native JSI functions ("Host Functions") from a JSI library, e.g. every function react-native-mmkv provides.
  • You can asynchronously dispatch calls to functions from "outside" using runOnJS from react-native-reanimated.

What's not possible?

  1. At the moment, only iOS is implemented. I cannot implement Android until react-native-reanimated gets published with source-code (no prebuilt .aar)
  2. Since the library uses JSI for synchronous native methods access, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use Flipper.
  3. All functions you are calling inside a custom thread, must be workletized to truly run on a separate thread. So add the 'worklet' directive at the top of every function you're calling in that thread (including the thread callback itself), and don't forget to install the Reanimated babel plugin.

License

MIT

Credits

Note: Technically this is not multithreading, but rather multiprocessing.

Issues
  • Android support (with `Android.mk`)

    Android support (with `Android.mk`)

    opened by mrousavy 1
  • Try support android

    Try support android

    The entire source code is written in C++, so I don't really have to do anything except finding the right CMakeLists configuration. That's going to be hard though, since I've never really used CMake before. Any help appreciated!

    Mission

    The user has react-native-reanimated installed via npm which lives on his machine as an .aar. react-native-multithreading is also an .aar. How do I "dynamically" include reanimated aar in my aar without copying the entire REA source code into my lib?

    opened by mrousavy 0
  • docs(SETUP.md): correct other JSI libs example

    docs(SETUP.md): correct other JSI libs example

    • [x] Correct the import path for the JSI module in the example
    • [x] ~~Add MMKV into the example - I feel most people would be using these together and could use the example.~~

    Also, I had to follow this suggested fix but replace mmkv with multithreading.

    opened by david-gettins 2
Releases(v1.1.1)
Owner
Marc Rousavy
they call me ranch cause I be dressing
Marc Rousavy
A multithreading library implemented in C

CthreAd A multi-threading library for C Programs Report Bug · Request Feature Table of Contents About The Project One-One Many-One Usage Testing Contr

Chetas Borse 6 May 6, 2021
C++React: A reactive programming library for C++11.

C++React is reactive programming library for C++14. It enables the declarative definition of data dependencies between state and event flows. Based on

Sebastian 952 Jun 19, 2022
An easy to use C++ Thread Pool

mvThreadPool (This library is available under a free and permissive license) mvThreadPool is a simple to use header only C++ threadpool based on work

Jonathan Hoffstadt 30 Jun 7, 2022
Simple and fast C library implementing a thread-safe API to manage hash-tables, linked lists, lock-free ring buffers and queues

libhl C library implementing a set of APIs to efficiently manage some basic data structures such as : hashtables, linked lists, queues, trees, ringbuf

Andrea Guzzo 383 Jul 1, 2022
Parallel-hashmap - A family of header-only, very fast and memory-friendly hashmap and btree containers.

The Parallel Hashmap Overview This repository aims to provide a set of excellent hash map implementations, as well as a btree alternative to std::map

Gregory Popovitch 1.5k Jun 27, 2022
Bistro: A fast, flexible toolkit for scheduling and running distributed tasks

Bistro is a flexible distributed scheduler, a high-performance framework supporting multiple paradigms while retaining ease of configuration, management, and monitoring.

Facebook 1k Jun 30, 2022
A fast multi-producer, multi-consumer lock-free concurrent queue for C++11

moodycamel::ConcurrentQueue An industrial-strength lock-free queue for C++. Note: If all you need is a single-producer, single-consumer queue, I have

Cameron 6.8k Jun 24, 2022
A fast single-producer, single-consumer lock-free queue for C++

A single-producer, single-consumer lock-free queue for C++ This mini-repository has my very own implementation of a lock-free queue (that I designed f

Cameron 2.7k Jul 3, 2022
Fast, generalized, implementation of the Chase-Lev lock-free work-stealing deque for C++17

riften::Deque A bleeding-edge lock-free, single-producer multi-consumer, Chase-Lev work stealing deque as presented in the paper "Dynamic Circular Wor

Conor Williams 113 May 29, 2022
Light, fast, threadpool for C++20

riften::Thiefpool A blazing-fast, lightweight, work-stealing thread-pool for C++20. Built on the lock-free concurrent riften::Deque. Usage #include "r

Conor Williams 60 Jun 8, 2022
lc is a fast multi-threaded line counter.

Fast multi-threaded line counter in Modern C++ (2-10x faster than `wc -l` for large files)

Pranav 12 Feb 17, 2022
Termite-jobs - Fast, multiplatform fiber based job dispatcher based on Naughty Dogs' GDC2015 talk.

NOTE This library is obsolete and may contain bugs. For maintained version checkout sx library. until I rip it from there and make a proper single-hea

Sepehr Taghdisian 35 Jan 9, 2022
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin

A CPU scheduler determines an order for the execution of its scheduled processes; it decides which process will run according to a certain data structure that keeps track of the processes in the system and their status.

null 11 Jul 14, 2021
A novel technique to communicate between threads using the standard ETHREAD structure

??️ dearg-thread-ipc-stealth Usage There are two main exported methods, one to read from another thread, and another to serve the content to another t

Lloyd 79 Jun 19, 2022
Exploration of x86-64 ISA using speculative execution.

Haruspex /həˈrʌspeks/ A religious official in ancient Rome who predicted the future or interpreted the meaning of events by examining the insides of b

Can Bölük 273 Jun 10, 2022
Discrete-event simulation in C++20 using coroutines

SimCpp20 SimCpp20 is a discrete-event simulation framework for C++20. It is similar to SimPy and aims to be easy to set up and use. Processes are defi

Felix Schütz 28 Apr 29, 2022
Thread pool - Thread pool using std::* primitives from C++17, with optional priority queue/greenthreading for POSIX.

thread_pool Thread pool using std::* primitives from C++11. Also includes a class for a priority thread pool. Requires concepts and C++17, including c

Tyler Hardin 74 Jun 15, 2022
Thread-pool - Thread pool implementation using c++11 threads

Table of Contents Introduction Build instructions Thread pool Queue Submit function Thread worker Usage example Use case#1 Use case#2 Use case#3 Futur

Mariano Trebino 595 Jun 26, 2022
Parallel implementation of Dijkstra's shortest path algorithm using MPI

Parallel implementation of Dijkstra's shortest path algorithm using MPI

Alex Diop 1 Jan 21, 2022