PERF/CLN: float-to-int casting
using float.is_integer is apparently much faster than casting and checking equality, especially for values between int32max and int64max (anecdotal based on small sample size)

```
cast1 = com.cast_scalar_indexer_master
cast2 = com.cast_scalar_indexer_PR

def cast3(key):
    # Effectively what we have in _maybe_cast_indexer in master
    if lib.is_float(key):
        try:
            ckey = int(key)
            if ckey == key:
                key = ckey
        except (OverflowError, ValueError, TypeError):
            pass
    return key

key1 = np.float64(17179869184.0)
key2 = float(key1) * 2**30             
key3 = np.float64(np.iinfo(np.int64).max)

In [87]: for func in [cast1, cast2, cast3]: 
    ...:     for key in [key1, key2, key3]: 
    ...:                 %timeit func(key) 
    ...:                                                                                                                                                                                                                                          

647 ns ± 3.71 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
559 ns ± 27.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
1.98 µs ± 19.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

360 ns ± 4.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
353 ns ± 3.11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
377 ns ± 6.54 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

568 ns ± 3.92 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
445 ns ± 15 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
1.91 µs ± 36.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
```

The middle three timeit results are the ones we get from this PR.