PERF: use new to_records() argument in to_stata()
State: closed

The `to_stata()` function spends ~25-50% of its time massaging string/different endian data and creating a `np.recarray` in a roundabout way. Using `column_dtypes` in `to_records()` allows some cleanup and for a decent performance bump:
```
$ asv compare upstream/master HEAD -s --sort ratio

Benchmarks that have improved:

       before           after         ratio
     [4cbee179]       [9bf67cc5]
     <to_stata~1>       <to_stata>
-         709±9ms         552±20ms     0.78  io.stata.Stata.time_write_stata('tw')
-        409±30ms         233±30ms     0.57  io.stata.Stata.time_write_stata('tq')
-        402±20ms         227±30ms     0.56  io.stata.Stata.time_write_stata('tc')
-         398±9ms         222±30ms     0.56  io.stata.Stata.time_write_stata('th')
-        420±20ms         231±30ms     0.55  io.stata.Stata.time_write_stata('tm')
-        396±10ms          214±3ms     0.54  io.stata.Stata.time_write_stata('ty')
-         389±8ms         207±10ms     0.53  io.stata.Stata.time_write_stata('td')

Benchmarks that have stayed the same:

       before           after         ratio
     [4cbee179]       [9bf67cc5]
     <to_stata~1>       <to_stata>
          527±6ms         563±30ms     1.07  io.stata.Stata.time_read_stata('th')
         507±20ms          531±9ms     1.05  io.stata.Stata.time_read_stata('ty')
         519±10ms         543±30ms     1.05  io.stata.Stata.time_read_stata('tm')
         484±10ms         504±10ms     1.04  io.stata.Stata.time_read_stata('tw')
          149±6ms          152±2ms     1.02  io.stata.Stata.time_read_stata('tc')
          152±3ms          153±8ms     1.01  io.stata.Stata.time_read_stata('td')
         533±20ms          533±6ms     1.00  io.stata.Stata.time_read_stata('tq')

```
- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Performance
description: Memory or execution speed performance
name: IO Stata
description: read_stata, to_stata

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=h1) Report
> Merging [#25045](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/4cbee179bd9ced459ef7865297110ec7e86f213f?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/25045/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master   #25045   +/-   ##
=======================================
  Coverage   92.38%   92.38%           
=======================================
  Files         166      166           
  Lines       52401    52401           
=======================================
  Hits        48409    48409           
  Misses       3992     3992
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.8% <ø> (ø)` | :arrow_up: |
| #single | `42.88% <ø> (ø)` | :arrow_up: |


------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=footer). Last update [4cbee17...85df94f](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=h1) Report
> Merging [#25045](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/da5f5eb6c11140a2bb9f84049d30ba7d89bdbfd0?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/25045/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master   #25045   +/-   ##
=======================================
  Coverage   92.37%   92.37%           
=======================================
  Files         166      166           
  Lines       52403    52403           
=======================================
  Hits        48405    48405           
  Misses       3998     3998
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.79% <ø> (ø)` | :arrow_up: |
| #single | `42.87% <ø> (ø)` | :arrow_up: |


------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=footer). Last update [da5f5eb...f8ebd68](https://codecov.io/gh/pandas-dev/pandas/pull/25045?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

cc @bashtage 
Code changes seem fine. Might need a benchmark to show the gains on strings though since these seem to be time conversion tests. 
@jreback Done. My last performance PR had added a duplicate "Performance Improvements" section, so cleaning that up now as well.

@bashtage Here's the benchmark in question - the single string column was enough to trigger the slow path, which this PR eliminates: https://github.com/pandas-dev/pandas/blob/master/asv_bench/benchmarks/io/stata.py
thanks @qwhelan