perflevels
v1.0.3
Published
Provides the number of physical CPU cores in each perflevel on macOS
Downloads
56
Maintainers
Readme
perflevels
Exports an array with the physical CPU core count in each perflevel
on macOS
(think "efficiency" vs "performance" cores), where the array index matches the
perflevel
index.
Exports an empty array on non-macOS platforms.
Examples
These examples assume that there are only 2 levels. Note that there could be more in the future, and the library could return an array longer than 2 elements, but as far as I know all M1 _____ machines only have 2 levels.
Basic
import perflevels from 'perflevels';
const [ efficiency, performance ] = perflevels;
console.log(efficiency, performance);
// 4, 4 on an M1 running macOS
import os from 'os';
console.log(os.cpus().length);
// 8 on an M1 running macOS
My use-case
Note that this uses another library, physical-cpu-count-async, to get the
total number of physical CPU cores. I use Infinity
as a default if we're not
on macOS or don't have multiple perflevels, so that Math.min
uses the
totalCores
result instead.
import perflevels from 'perflevels';
import totalCores from 'physical-cpu-count-async';
const [ , performanceCores=Infinity ] = perflevels;
const coresToUse = Math.min(totalCores - 2, performanceCores)
On an 8-physical-core AMD chip, this will use 6 cores. On an 8-physical-core 4-performance-core M1 chip, this will use 4 cores.
Async
You might not want to wait for system commands to run every time you start your
app. You can always defer the import, or start the import without await
ing it!
// Defer import until you know you need it
async function startThingInParallelMaybe() {
const { default: [ efficiency, performance ] } = await import('perflevels');
await startTheThing(performance);
}
// NOTE: no await. Starts import, but doesn't block on it until it's needed
const perfLevelsPromise = import('perflevels');
async function startThingInParallelLater() {
const { default: [ efficiency, performance ] } = await perfLevelsPromise;
await startTheThing(performance);
}
Use Case
Working with multithreading in Node.js processes is super useful. However, determining the number of workloads you can run reliably in parallel can be hard when some of the reported CPU cores are different than others, which hasn't been a problem in the past.
I set up some local development end-to-end browser tests that run in parallel
and use numberOfCores - 2
(keeping 2 "free" for running the backend and
database). However, the difference between the performance and efficiency cores
is so much that it would frequently fail the tests on my M1 machine, where 4
performance and 4 efficiency cores are available.
This lets me differentiate between the two, and only run 4 tests where I only have 4 performance cores.
Known Limitations
Only returns real values on macOS.
If other platforms have similarly lopsided CPUs, let me know, and I'll try to add support! I considered making other platforms return a singleton array with the results of physical-cpu-count-async, but that would have made things more complicated for my use-case, so I opted to return nothing.