Skip to content

Optimize multiplication by 1 (especially integers) #737

@dg-pb

Description

@dg-pb

Identity fast path for * 1 on immutable types

Currently, multiplying by 1 on numeric types creates a new object and goes through the full multiplication code path, despite being a no-op semantically:

$ ./python.exe -m timeit -s 'a=1e9' 'a * 1'
10000000 loops, best of 5: 31.3 nsec per loop

For immutable types, x * 1 could simply return x — no new allocation, no arithmetic.

Motivation

A common pattern involves a scaling constant that is frequently 1:

seq = list(range(10))
lb = 4
ub = 8

scale = 2
scaled_seq = [x for x in seq for _ in range(scale)]
for _ in range(1e9):
    idx = do_something(scaled_seq, lb * scale, ub * scale)

    # scale back
    idx //= scale
    do_something_with_original(seq, idx)

When scale == 1, all multiplication and allocation is pure overhead. An identity check before the multiply would eliminate it with no branching cost.

Type candidates

  1. int — straightforward
  2. tuple - straightforward
  3. float — needs to handle NaN * 1 correctly per IEEE 754 (must still return a new NaN)
  4. Decimal / Fraction — most expensive to construct, largest potential win, may have edge case nuances

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions