Large array literal causes slow compilation
I have a large array of the form
static mut ARRAY: [AtomicU64; LARGE_NUMBER] = [
ATOMIC_U64_INIT, ATOMIC_U64_INIT, ...
];
where LARGE_NUMBER = 512 * 1024. ATOMIC_U64_INIT is not Copy, so it's not obvious how to express this differently. I don't even think I even legally can use a [u64; LARGE_NUMBER] and transmute on use because u64 has aliasing guarantees that AtomicU64 breaks.
This ends up adding more than 10s to my compile times. time-passes, filtering out passes that take <0.1s above their baseline, shows
time: 0.594; rss: 322MB parsing
time: 0.295; rss: 349MB expansion
time: 0.244; rss: 404MB name resolution
time: 0.126; rss: 549MB lowering ast -> hir
time: 0.104; rss: 358MB region resolution
time: 0.148; rss: 358MB static item recursion checking
time: 0.497; rss: 359MB compute_incremental_hashes_map
time: 1.643; rss: 437MB item-types checking
time: 0.562; rss: 436MB const checking
time: 0.115; rss: 436MB privacy checking
time: 0.568; rss: 492MB MIR dump
time: 0.136; rss: 475MB death checking
time: 0.164; rss: 475MB stability checking
time: 0.559; rss: 475MB lint checking
time: 3.098; rss: 523MB translation item collection
time: 5.724; rss: 447MB translation
There's a full version available elsewhere, but it's not really more interesting.
You can absolutely transmute if you use an
UnsafeCell, which discard aliasing assumptions.#![feature(const_fn, integer_atomics)] use std::cell::UnsafeCell; use std::sync::atomic::AtomicU64; pub struct SyncCell<T>(UnsafeCell<T>); unsafe impl<T: Sync> Sync for SyncCell<T> {} static XYZ: SyncCell<[u64; 1024*512]> = SyncCell(UnsafeCell::new([0; 1024*512])); pub fn get_xyz() -> &'static [AtomicU64; 1024*512] { unsafe {&*(XYZ.0.get() as *mut _)} } fn main() {}Ariel Ben-Yehuda at 2016-10-14 09:18:21
That's much better, thanks! I'll leave the issue open for now, since this indicates a bottleneck in translation, but it's no longer an immediate problem.
Joshua Landau at 2016-10-14 10:34:17
https://gist.github.com/Mark-Simulacrum/a83196ed84920c37804654ec39a7ebe9 is the full time-passes log from today, with the relevant passes:
time: 1.191; rss: 206MB parsing time: 1.578; rss: 391MB stability checking time: 14.975; rss: 494MB item-types checking *** time: 2.139; rss: 532MB const checking time: 3.860; rss: 556MB borrow checking time: 1.065; rss: 556MB lint checking time: 2.718; rss: 556MB translation item collection time: 11.775; rss: 560MB translation ***Mark Rousskov at 2017-05-14 23:46:55
See https://github.com/rust-lang/rust/issues/52868#issue-345825358 for a quick test case demonstrating that compile time scales quadratically with array size.
Ralf Jung at 2018-08-06 13:56:44
Triage: Still reproduces with nightly-2023-11-17 using the following reproducer taken from #58523.
pub fn main() { let mut _buf = vec![0u8; 1 << 32]; (&[0u8; (1 << 32) - 8]); }Martin Nordholts at 2023-11-20 20:01:59