Repository: pola-rs/polars
File: crates/polars-ops/src/chunked_array/binary/namespace.rs (Rust)

Code before:
            ca.apply_values(|s| general_purpose::STANDARD.encode(s).into_bytes().into())
                .cast_unchecked(&DataType::String)
                .unwrap()
        }
    }

    #[cfg(feature = "binary_encoding")]
    fn reinterpret(&self, dtype: &DataType, is_little_endian: bool) -> PolarsResult<Series> {
        unsafe {
            Ok(Series::from_chunks_and_dtype_unchecked(
                self.as_binary().name().clone(),
                self._reinterpret_inner(dtype, is_little_endian)?,
                dtype,
            ))
        }
    }

    #[cfg(feature = "binary_encoding")]
    fn _reinterpret_inner(
        &self,
        dtype: &DataType,
        is_little_endian: bool,
    ) -> PolarsResult<Vec<Box<dyn Array>>> {
        let ca = self.as_binary();

        match dtype.to_arrow(CompatLevel::newest()).to_physical_type() {
            PhysicalType::Primitive(ty) => {
                let arrow_data_type = dtype
                    .to_arrow(CompatLevel::newest())
                    .underlying_physical_type();
                with_match_primitive_type!(ty, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            binview_to_primitive_dyn::<$T>(
                                &**chunk,
                                &arrow_data_type,
                                is_little_endian,
                            )
                        }).collect()
                    }
                })
            },
            #[cfg(feature = "dtype-array")]
            PhysicalType::FixedSizeList => {
                // In theory the IR dispatch should've made sure we have the
                // correct types, but we can't prove it so check again. In
                // particular, no nesting beyond the top-level Array:
                let Some(PhysicalType::Primitive(primitive_type)) = dtype
                    .inner_dtype()
                    .map(|dt| dt.to_arrow(CompatLevel::newest()).to_physical_type())
                else {

Review comment (performance):
~~_I think we can make this a bit cleaner:_~~
* ~~_Please do the dtype checks the polars-native `DataType` instead of on the physical type_~~
* ~~_Can we try to remove the conversions to arrow types altogether. I think it should be possible to just use the `with_match_physical_numeric_polars_type` macro on the polars-native dtype._~~

In pseudocode:
```rust
match dtype {
    dt if dt.is_primitive_numeric() || ..you may need others => {
        ..
        with_match_physical_numeric_polars_type!(dtype, ..)
    }
    #[cfg(feature = "dtype-array")]
    DataType::Array(inner_dtype, width) if inner_dtype.is_primitive_numeric() || .. => {
       ..
       with_match_physical_numeric_polars_type!(inner_dtype, ..)
    },
    _ => Err(..)
```

~~_And as a side note, I can see a lot of duplicate / upfront arrow dtype conversions in the existing code. This is something you should avoid, as converting a dtype can lead to unnecessary allocations on nested types. This may seem like something minor, but these small things can add up in the codebase. This is especially true when doing things on a low-level like in Rust. Sometimes you need allocations, and I'm not saying that you should go out of your way to avoid them, but this code here was really just a matter of storing it once in a variable._~~


Code after:
        }
    }

    #[cfg(feature = "binary_encoding")]
    fn reinterpret(&self, dtype: &DataType, is_little_endian: bool) -> PolarsResult<Series> {
        unsafe {
            Ok(Series::from_chunks_and_dtype_unchecked(
                self.as_binary().name().clone(),
                self._reinterpret_inner(dtype, is_little_endian)?,
                dtype,
            ))
        }
    }

    #[cfg(feature = "binary_encoding")]
    fn _reinterpret_inner(
        &self,
        dtype: &DataType,
        is_little_endian: bool,
    ) -> PolarsResult<Vec<Box<dyn Array>>> {
        use polars_core::with_match_physical_numeric_polars_type;

        let ca = self.as_binary();

        match dtype {
            dtype if dtype.is_primitive_numeric() || dtype.is_temporal() => {
                let dtype = dtype.to_physical();
                let arrow_data_type = dtype
                    .to_arrow(CompatLevel::newest())
                    .underlying_physical_type();
                with_match_physical_numeric_polars_type!(dtype, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            binview_to_primitive_dyn::<<$T as PolarsNumericType>::Native>(
                                &**chunk,
                                &arrow_data_type,
                                is_little_endian,
                            )
                        }).collect()
                    }
                })
            },
            #[cfg(feature = "dtype-array")]
            DataType::Array(inner_dtype, array_width)
                if inner_dtype.is_primitive_numeric() || inner_dtype.is_temporal() =>
            {
                let inner_dtype = inner_dtype.to_physical();
                let result: Vec<ArrayRef> = with_match_physical_numeric_polars_type!(inner_dtype, |$T| {
                    unsafe {
                        ca.chunks().iter().map(|chunk| {
                            binview_to_fixed_size_list_dyn::<<$T as PolarsNumericType>::Native>(