Repository: meilisearch/meilisearch
File: crates/meilisearch/src/option.rs (Rust)

Code before:

impl IndexerOpts {
    /// Exports the values to their corresponding env vars if they are not set.
    pub fn export_to_env(self) {
        let IndexerOpts { max_indexing_memory, max_indexing_threads, skip_index_budget: _ } = self;
        if let Some(max_indexing_memory) = max_indexing_memory.0 {
            export_to_env_if_not_present(
                MEILI_MAX_INDEXING_MEMORY,
                max_indexing_memory.to_string(),
            );
        }
        if let Some(max_indexing_threads) = max_indexing_threads.0 {
            export_to_env_if_not_present(
                MEILI_MAX_INDEXING_THREADS,
                max_indexing_threads.to_string(),
            );
        }
    }
}

impl TryFrom<&IndexerOpts> for IndexerConfig {
    type Error = anyhow::Error;

    fn try_from(other: &IndexerOpts) -> Result<Self, Self::Error> {
        // use 1/2 cpu threads if no value specified
        let max_indexing_threads = other.max_indexing_threads.unwrap_or(num_cpus::get() / 2);

        let thread_pool = ThreadPoolNoAbortBuilder::new()
            .thread_name(|index| format!("indexing-thread:{index}"))
            .num_threads(max_indexing_threads)
            .build()?;

        Ok(Self {
            thread_pool,
            log_every_n: Some(DEFAULT_LOG_EVERY_N),
            max_memory: other.max_indexing_memory.map(|b| b.as_u64() as usize),
            max_threads: *other.max_indexing_threads,
            max_positions_per_attributes: None,
            skip_index_budget: other.skip_index_budget,
            ..Default::default()
        })
    }
}

/// A type used to detect the max memory available and use 2/3 of it.
#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
pub struct MaxMemory(Option<Byte>);

impl FromStr for MaxMemory {
    type Err = ParseError;


Review comment (suggestion):
```suggestion
        let max_indexing_threads = other.max_indexing_threads.unwrap_or_else(|| num_cpus::get() / 2);
```
Do not make additional computation unless really necessary.

Code after:

impl IndexerOpts {
    /// Exports the values to their corresponding env vars if they are not set.
    pub fn export_to_env(self) {
        let IndexerOpts { max_indexing_memory, max_indexing_threads, skip_index_budget: _ } = self;
        if let Some(max_indexing_memory) = max_indexing_memory.0 {
            export_to_env_if_not_present(
                MEILI_MAX_INDEXING_MEMORY,
                max_indexing_memory.to_string(),
            );
        }
        if let Some(max_indexing_threads) = max_indexing_threads.0 {
            export_to_env_if_not_present(
                MEILI_MAX_INDEXING_THREADS,
                max_indexing_threads.to_string(),
            );
        }
    }
}

impl TryFrom<&IndexerOpts> for IndexerConfig {
    type Error = anyhow::Error;

    fn try_from(other: &IndexerOpts) -> Result<Self, Self::Error> {
        let thread_pool = ThreadPoolNoAbortBuilder::new_for_indexing()
            .num_threads(other.max_indexing_threads.unwrap_or_else(|| num_cpus::get() / 2))
            .build()?;

        Ok(Self {
            thread_pool,
            log_every_n: Some(DEFAULT_LOG_EVERY_N),
            max_memory: other.max_indexing_memory.map(|b| b.as_u64() as usize),
            max_threads: *other.max_indexing_threads,
            max_positions_per_attributes: None,
            skip_index_budget: other.skip_index_budget,
            ..Default::default()
        })
    }
}

/// A type used to detect the max memory available and use 2/3 of it.
#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
pub struct MaxMemory(Option<Byte>);

impl FromStr for MaxMemory {
    type Err = ParseError;

    fn from_str(s: &str) -> Result<MaxMemory, Self::Err> {
        Byte::from_str(s).map(Some).map(MaxMemory)
    }
}