# `Benchee.Conversion.Scale`
[🔗](https://github.com/bencheeorg/benchee/blob/1.5.1/lib/benchee/conversion/scale.ex#L1)

Functions for scaling values to other units. Different domains handle
this task differently, for example durations and counts.

See `Benchee.Conversion.Count` and `Benchee.Conversion.Duration` for examples

# `any_unit`

```elixir
@type any_unit() :: unit() | unit_atom()
```

# `scaled_number`

```elixir
@type scaled_number() :: {number(), unit()}
```

# `scaling_strategy`

```elixir
@type scaling_strategy() :: :best | :largest | :smallest | :none
```

# `unit`

```elixir
@type unit() :: Benchee.Conversion.Unit.t()
```

# `unit_atom`

```elixir
@type unit_atom() :: atom()
```

# `base_unit`

```elixir
@callback base_unit() :: unit()
```

Returns the base_unit in which Benchee takes its measurements, which in
general is the smallest supported unit.

# `best`

```elixir
@callback best(
  list(),
  keyword()
) :: unit()
```

Finds the best fit unit for a list of numbers in a domain's base unit.
"Best fit" is the most common unit, or (in case of tie) the largest of the
most common units.

# `convert`

```elixir
@callback convert(
  {number(), any_unit()},
  any_unit()
) :: scaled_number()
```

Takes a tuple of a number and a unit and a unit to be converted to, returning
the the number scaled to the new unit and the new unit.

# `scale`

```elixir
@callback scale(number()) :: scaled_number()
```

Scales a number in a domain's base unit to an equivalent value in the best
fit unit. Results are a `{number, unit}` tuple. See `Benchee.Conversion.Count` and
`Benchee.Conversion.Duration` for examples.

# `scale`

```elixir
@callback scale(number(), any_unit()) :: number()
```

Scales a number in a domain's base unit to an equivalent value in the
specified unit.
See `Benchee.Conversion.Count` and `Benchee.Conversion.Duration` for examples.

# `unit_for`

```elixir
@callback unit_for(any_unit()) :: unit()
```

Given the atom representation of a unit (`:hour`) return the appropriate
`Benchee.Conversion.Unit` struct.

# `units`

```elixir
@callback units() :: [unit()]
```

List of all the units supported by this type.

# `best_unit`

Given a `list` of number values and a `module` describing the domain of the
values (e.g. Duration, Count), finds the "best fit" unit for the list as a
whole.

The best fit unit for a given value is the smallest unit in the domain for
which the scaled value is at least 1. For example, the best fit unit for a
count of 1_000_000 would be `:million`.

The best fit unit for the list as a whole depends on the `:strategy` passed
in `opts`:

* `:best`     - the most frequent best fit unit. In case of tie, the
largest of the most frequent units
* `:largest`  - the largest best fit unit
* `:smallest` - the smallest best fit unit
* `:none`     - the domain's base (unscaled) unit

## Examples

    iex> list = [1, 101, 1_001, 10_001, 100_001, 1_000_001]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :best).name
    :thousand

    iex> list = [1, 101, 1_001, 10_001, 100_001, 1_000_001]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :smallest).name
    :one

    iex> list = [1, 101, 1_001, 10_001, 100_001, 1_000_001]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :largest).name
    :million

    iex> list = []
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :best).name
    :one

    iex> list = [nil]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :best).name
    :one

    iex> list = [nil, nil, nil, nil]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :best).name
    :one

    iex> list = [nil, nil, nil, nil, 2_000]
    ...> best_unit(list, Benchee.Conversion.Count, strategy: :best).name
    :thousand

# `convert`

Used internally to implement scaling in the modules without duplication.

# `scale`

Used internally for scaling but only supports scaling with actual units.

## Examples

    iex> unit = %Benchee.Conversion.Unit{magnitude: 1000}
    ...> scale(12345, unit)
    12.345

# `scale`

Used internally by implemented units to handle their scaling with units and
without.

## Examples

    iex> scale(12345, :thousand, Benchee.Conversion.Count)
    12.345

# `unit_for`

Lookup a unit by its `atom` presentation for the representation of supported
units. Used by `Benchee.Conversion.Duration` and `Benchee.Conversion.Count`.

