gh-38152: Improve performance of computing columns of matrices over GF(2)
In response to issue https://github.com/sagemath/sage/issues/38150 I
have adjusted the request for columns over dense matrices over GF(2) by
replacing the standard call to columns with a transpose followed by a
request of rows.
This results in almost a 1000x speed up for large matrices (for the
example in the issue).
### Old Implementation
```py
sage: M2 = random_matrix(GF(2), 2, 2)
sage: %time _ = M2.columns()
CPU times: user 4.14 ms, sys: 1.67 ms, total: 5.81 ms
Wall time: 10.9 ms
sage: %time _ = M2.rows()
CPU times: user 109 µs, sys: 130 µs, total: 239 µs
Wall time: 1.39 ms
sage: M2 = random_matrix(GF(2), 200, 200)
sage: %time _ = M2.columns()
CPU times: user 87.9 ms, sys: 1.32 ms, total: 89.2 ms
Wall time: 88.3 ms
sage: %time _ = M2.rows()
CPU times: user 811 µs, sys: 96 µs, total: 907 µs
Wall time: 912 µs
sage: M2 = random_matrix(GF(2), 2000, 2000)
sage: %time _ = M2.columns()
CPU times: user 7.94 s, sys: 9.11 ms, total: 7.95 s
Wall time: 7.97 s
sage: %time _ = M2.rows()
CPU times: user 7.49 ms, sys: 770 µs, total: 8.26 ms
Wall time: 7.97 ms
```
### New Implementation
```py
sage: M2 = random_matrix(GF(2), 2, 2)
sage: %time _ = M2.columns()
CPU times: user 1.01 ms, sys: 261 µs, total: 1.27 ms
Wall time: 3.75 ms
sage: %time _ = M2.rows()
CPU times: user 54 µs, sys: 8 µs, total: 62 µs
Wall time: 65.1 µs
sage: M2 = random_matrix(GF(2), 200, 200)
sage: %time _ = M2.columns()
CPU times: user 1.09 ms, sys: 40 µs, total: 1.13 ms
Wall time: 1.13 ms
sage: %time _ = M2.rows()
CPU times: user 712 µs, sys: 15 µs, total: 727 µs
Wall time: 732 µs
sage: M2 = random_matrix(GF(2), 2000, 2000)
sage: %time _ = M2.columns()
CPU times: user 9.07 ms, sys: 746 µs, total: 9.82 ms
Wall time: 9.54 ms
sage: %time _ = M2.rows()
CPU times: user 7.82 ms, sys: 687 µs, total: 8.51 ms
Wall time: 8.18 ms
```
Fixes https://github.com/sagemath/sage/issues/38150
URL: https://github.com/sagemath/sage/pull/38152
Reported by: Giacomo Pope
Reviewer(s): grhkm21