Parallel Computations
Powerful Parallel Computing with BoxLang's Async Framework
Introduced in v1.4.0
BoxLang's async framework provides powerful tools for parallel computing, allowing you to execute multiple operations concurrently and efficiently process large datasets. Whether you're processing arrays, transforming data structures, or running independent computations, BoxLang's parallel computing BIFs give you the tools to maximize performance while maintaining code simplicity.
Sequential: Task1 → Task2 → Task3 → Task4 (16 seconds)
🟦 🟦 🟦 🟦
Parallel: Task1 ↘
Task2 → Results (4 seconds)
Task3 ↗
Task4 ↙
🟦🟦🟦🟦🎯 Core Parallel Computing BIFs
BoxLang provides several Built-In Functions (BIFs) for parallel computing:
asyncAll()
Execute futures in parallel
Array of futures/functions
BoxFuture
asyncAny()
Race multiple futures
Array of futures/functions
BoxFuture
asyncRun()
Execute single function async
Function
BoxFuture
asyncAllApply()
Apply function to collection in parallel
Array/Struct + mapper
Array/Struct
futureNew()
Create new BoxFuture
Value/Function
BoxFuture
🚀 Basic Parallel Execution
asyncAll() - Execute All in Parallel
asyncAll() - Execute All in ParallelThe asyncAll() BIF executes multiple operations concurrently and returns results in order:
Advanced Example with Mixed Types:
asyncAny() - Race to the Finish
asyncAny() - Race to the FinishThe asyncAny() BIF returns the result of the first operation to complete:
Timeout and Fallback Pattern:
🔄 Data Processing with asyncAllApply()
asyncAllApply()The asyncAllApply() BIF is perfect for applying transformations to collections in parallel:
Array Processing
Struct Processing
With Error Handling
With Custom Executor and Timeout
🔢 Collection Parallel Methods
BoxLang provides powerful parallel processing capabilities for all collection types (arrays, lists, queries, and structs) through parallel versions of common iteration methods. These methods can dramatically improve performance when processing large collections or when the callback functions involve expensive operations.
Just make sure you understand the intricacies of creating and managing parallel tasks, as improper use can lead to resource contention or inefficient execution.
📋 Supported Collection Types
All parallel methods work across these data types:
Array
arrayEach(), arrayEvery(), arrayFilter(), arrayMap(), arrayNone(), arraySome()
List
listEach(), listEvery(), listFilter(), listMap(), listNone(), listSome()
Query
queryEach(), queryEvery(), queryFilter(), queryMap(), queryNone(), querySome()
Struct
structEach(), structEvery(), structFilter(), structMap(), structNone(), structSome()
🎯 Collection Method Purposes
Each collection method serves a specific purpose in data processing:
Each
Iteration with side effects
Collection + callback
void
Logging, notifications, updating external state
Every
Universal validation
Collection + predicate
boolean
Check if ALL items meet the criteria predicate
Filter
Selective extraction
Collection + predicate
New collection
Extract items matching conditions
Map
Transformation
Collection + mapper
New collection
Transform each item to new form
None
Negative validation
Collection + predicate
boolean
Ensure NO items meet the criteria predicate
Some
Existence check
Collection + predicate
boolean
Check if ANY items meet the criteria predicate
🔄 Each - Perform Actions
Execute side effects for each item without returning results:
✅ Every - Validate All
Test whether ALL items in a collection meet a condition:
🔍 Filter - Extract Matching Items
Create a new collection containing only items that meet criteria:
🔄 Map - Transform Items
Transform each item into a new form, creating a new collection:
❌ None - Ensure Absence
Verify that NO items in the collection meet a condition:
🔎 Some - Check Existence
Test whether AT LEAST ONE item meets a condition:
🎛️ Parallel Execution Parameters
All collection parallel methods support these consistent parameters:
Execution Modes:
parallel: false- Sequential execution (default)parallel: true, maxThreads: null- Uses common ForkJoinPool (automatic thread count)parallel: true, maxThreads: N- Creates custom ForkJoinPool with N threadsparallel: true, virtual: true- Uses virtual threads for unlimited concurrencyparallel: true, maxThreads: true- Shorthand for virtual threads (positional syntax)
🔄 Array Parallel Processing
📝 List Parallel Processing
List methods include additional delimiter parameters before parallel options:
🗄️ Query Parallel Processing
🏗️ Struct Parallel Processing
🎯 Method-Specific Examples
Each - Side Effects
Each - Side EffectsEvery - Validation
Every - ValidationSome - Existence Check
Some - Existence CheckNone - Negative Validation
None - Negative Validation⚡ Performance Benefits
🌟 Virtual Threads: The Game Changer
Introduced in BoxLang v1.5.0
Virtual threads are lightweight, managed by the JVM, and perfect for I/O-intensive operations. Unlike platform threads, you can create millions of virtual threads without performance degradation.
🎯 When to Use Virtual Threads
✅ Perfect for Virtual Threads:
Network I/O: API calls, database queries, file downloads
File Operations: Reading/writing many files
External Service Calls: Microservice communication
Blocking Operations: Any operation that waits
❌ Better with Platform Threads:
CPU-Intensive Work: Mathematical calculations, data processing
Memory-Intensive Operations: Large object manipulation
Short-Running Tasks: Operations that complete quickly
🔄 Virtual Thread Examples
Network I/O Operations
Database Operations
File Processing
🆚 Virtual vs Platform Threads Comparison
Max Concurrent
~1,000-5,000
Millions+
Memory per Thread
~2MB stack
~Few KB
Creation Cost
Expensive
Cheap
Best For
CPU-intensive
I/O-intensive
JVM Management
OS-scheduled
JVM-managed
Blocking Behavior
Blocks OS thread
Suspends virtually
📊 Performance Comparison
🎛️ Best Practices for Collection Parallel Processing
1. Choose Appropriate Thread Count
2. Use Parallel Processing for Right-Sized Collections
3. Expensive Operations Benefit Most
⚡ Single Async Operations
asyncRun() - Basic Async Execution
asyncRun() - Basic Async ExecutionWith Custom Executor:
futureNew() - Creating Futures
futureNew() - Creating Futures🎛️ Advanced Patterns
Pipeline Processing
Fan-Out/Fan-In Pattern
Retry with Exponential Backoff
🛠️ Executor Management
Using Custom Executors
🚨 Thread Cancellation Control
For scenarios where you need to cancel all running threads, use a custom executor that you can shutdown:
⚠️ Important Notes on Cancellation:
Thread cancellation is cooperative - tasks must check for interruption
Use
Thread.interrupted()orThread.currentThread().isInterrupted()in your codeNot all operations can be cancelled (e.g., blocking I/O)
Cancellation may not be immediate
📊 Performance Monitoring
Timing Parallel Operations
Memory and Resource Monitoring
🎯 Best Practices
✅ Do's
Choose the Right Tool:
Choose the Right Threading Model:
Handle Errors Gracefully:
Use Appropriate Executors:
❌ Don'ts
Don't Block in Parallel Code:
Don't Use Virtual Threads for CPU-Intensive Work:
Don't Create Too Many Platform Threads:
Don't Forget Resource Cleanup:
🔗 Related Documentation
Async Pipelines - For chaining asynchronous operations
Executors - For managing thread pools and execution
Scheduled Tasks - For time-based parallel execution
📈 Performance Comparison
With BoxLang's parallel computing capabilities, you can dramatically improve application performance by leveraging multiple CPU cores and concurrent execution. Choose the right BIF for your use case, handle errors properly, and always consider resource management for optimal results.
Last updated
Was this helpful?
