## Optimized Array Formula
This formula is faster than my comparable array formula at the end. I favor shorter code where possible but apparently, that doesn't always go hand-in-hand with shorter execution time.

```
LET(rng,A1:A, arr,ARRAY_CONSTRAIN(rng,MAX(FILTER(ROW(rng), rng<>"")),1),
  m,INDEX(IFS(arr="",,ISNUMBER(arr),,1,IFERROR(REGEXEXTRACT(arr, " (\w)illion")))),
  v,IF(m="",,REGEXEXTRACT(arr, "([\d\.]*) ")),
  ARRAYFORMULA(IFS(m="m",v*10^6, m="d",v*10^9, 1,arr)))
```

1. `rng` references Column A
2. `arr` stores an array created by removing any empty rows after the last populated cell in `rng`. 
3. `m` returns an array of **m**ultipliers by processing the values in `arr` such that it has a:
    1. blank, if `arr` is a number or a blank,
    2. a single word character `\w`, if one is captured from the beginning of a text string using the regular expression `(\w)illion`.  Presumably it would be an `m` from **m**illion or `b` from **b**illion, but other incidental captures aren't a concern.
    3. lastly the value might be an error if there are string in Column A that don't match `(\w)illion`. This is also not a concern.
4. `v` stores an array of the same dimensions as `m` made up of blanks where `m` is blank, and extracts numbers from `arr` wherever `m` successfully extracted a single word character.
5. Finally, inside an ARRAYFORMULA, IFS evaluates multiple conditions, returning the value corresponding to the **first** true condition. 
    1. Conditions one and two check if `m` contains either the letter `"m"` or `"b"` returning either `v*10^6` or `v*10^9` respectively if one of them is true.
    2. If the previous two conditions return false, then the original value from `arr` / Column A is returned (text string, number, whatever).  To achieve this the last condition is set to `1`, which is equivalent to `TRUE`, therefore if ever the condition is reached, it must always succeed. This approach is why most errors generated in the earlier stages are not relevant as, if there is no `"m"` or `"b"` the formula returns the original value.


-------------
## Earlier Answer

[Martin's answer][1] is a good approach and originally I created a slight variation of it adding only some code reduction and extending it to work as an array formula. I found later that changing the approach resulted in better performance.

> **Credit:** [Martin's Original Formula][1]:
> ```
> =IF(A1="","",IF(ISNUMBER(A1),A1,VALUE(REGEXEXTRACT(A1,"[0-9\.]*"))*
>    IF(REGEXMATCH(A1,"million"),1000000,IF(REGEXMATCH(A1,"billion"),1000000000,1))))
>```


##### Variation on Martin's
```
=IFS(A1="",, ISNUMBER(A1),A1, 1,REGEXEXTRACT(A1,"[\d\.]*") * 10^ 
   (REGEXMATCH(A1,"m")*6 + REGEXMATCH(A1,"b")*9))
```

##### Array Formula Version
```
=LET(rng,A1:A, INDEX(
   IFS(rng="",, ISNUMBER(rng),rng, 1,REGEXEXTRACT(rng,"[\d\.]*") * 10^ 
     (REGEXMATCH(rng,"m")*6 + REGEXMATCH(rng,"b")*9))))
```

  [1]: https://webapps.stackexchange.com/a/175555