# Is unpacking faster than indexing?

This is a strange story.

One morning, I woke up and wrote a few lines of code. Then, there came an interesting situation. I need to assign two elements of an array to two variables. There are many ways of achieving this in python.

If you're a javascript developer, your instinct should say this is the way.

```javascript
const [x,y] = items;
```

Suppose, I've got an array `[1,2]` and I need to assign two variables to this value. Something like follow:

```python
a = 1
b = 2
```

I did the natural thing I was used to doing, unpacking the variable.

```python
a, b = items
```

This works with charm. But suddenly I remember of an another way. What if I index the array and grab the elements that way.

```python
a, b = items[0], items[1]
```
Or even.

```python
a = items[0]
b = items[1]
```

Now, I want to profile this code. I know this is over-engineering at max but let's see what exactly happens.

First I wrote the same implementation in python and disassembled the code.

```
In [15]: def x():
    ...:     a , b = items
    ...:     return
    ...:

In [16]: def y():
    ...:     a = items[0]
    ...:     b = items[1]
    ...:     return
    ...:

In [17]: dis(x)
  2           0 LOAD_GLOBAL              0 (items)
              2 UNPACK_SEQUENCE          2
              4 STORE_FAST               0 (a)
              6 STORE_FAST               1 (b)

  3           8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

In [18]: dis(y)
  2           0 LOAD_GLOBAL              0 (items)
              2 LOAD_CONST               1 (0)
              4 BINARY_SUBSCR
              6 STORE_FAST               0 (a)

  3           8 LOAD_GLOBAL              0 (items)
             10 LOAD_CONST               2 (1)
             12 BINARY_SUBSCR
             14 STORE_FAST               1 (b)

  4          16 LOAD_CONST               0 (None)
             18 RETURN_VALUE

In [19]:

```

Do you see the extra overhead when I index the value? First, it need to load the constant i.e. index value, then perform the subscription. The store the value in `a`. This is a long way of doing it.

If I look at the other code, which is unpacking. One instruction `UNPACK_SEQUENCE` is capable of returning all the values and it's followed by two store instructions. 

Even by intuition, I suppose the first function `(x)` will run faster.

Now, let's compare the execution time.

```
In [19]: %timeit x()
84.3 ns ± 3.59 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [20]: %timeit y()
108 ns ± 2.42 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
```

To no surprise, the unpacking beats the indexing by around ~24ns. This isn't the kind of optimization you should be thinking when writing a code. Write a clean, readable testable code.

Don't abuse your codebase with lines like the following:

```
a ,= items
# use this
b = items[0]
```

