> ## Documentation Index
> Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# June 10, 2026 — Group send: participant-list hash via single arena

> participant_list_hash now formats all device JIDs into one shared string buffer and sorts lightweight range views, cutting per-call heap allocations from O(n) to 3 for an 800-device group.

## Performance

**Group send: `participant_list_hash` uses a shared arena instead of one `String` per device ([#822](https://github.com/oxidezap/whatsapp-rust/pull/822))**

`participant_list_hash` computes the `phash` that travels on every group send (since #678 it is included on all sends, not just multi-device ones). Previously it collected all participant JIDs into a `Vec<String>` — one heap `String` per device — sorted them, and hashed the concatenation. For an 800-device group this was 801 discarded allocations per message on the hot send path.

**Arena approach.** All device JIDs are now formatted into a single shared `String` (the arena). A second `Vec<(usize, usize)>` stores `(start, end)` range pairs into the arena. Sorting those range pairs by `&arena[start..end]` is lexicographically identical to sorting the individual strings, so the resulting SHA-256 + base64 hash is byte-for-byte the same as before. The existing pinned cross-implementation test vectors (`phash_crosscheck_vectors`, locked against whatsmeow and WA Web) pass unchanged.

**Allocation counts (release, 800 devices, 1 000 iterations):**

|                                                                      | Allocations per call |
| -------------------------------------------------------------------- | -------------------- |
| Before (one `String` per device + sort)                              | 801                  |
| After (arena + range sort, full function including SHA-256 + base64) | 3                    |

Wall time is dominated by the SHA-256 over \~26 KB of concatenated JIDs and stays flat; the win is 798 fewer allocations per group send.

**New public item — `Jid::push_ad_to`**

A new `#[inline]` method on `Jid` in `wacore-binary`:

```rust theme={null}
pub fn push_ad_to(&self, buf: &mut String)
```

Appends the AD-string form (`user.agent:device@server`) directly into an existing `String` buffer without allocating a new one. `to_ad_string` now delegates to it, keeping identical output. Use `push_ad_to` when batching many JIDs into a single buffer.

**No breaking changes.** `to_ad_string` output is unchanged; `push_ad_to` is purely additive.
