回答編集履歴
5
追記
answer
CHANGED
@@ -79,8 +79,8 @@
|
|
79
79
|
for(i=0; i < nh; i++) {
|
80
80
|
result16[i] = buf16[i] >> 8 | buf16[i] << 8;
|
81
81
|
}
|
82
|
+
|
82
83
|
result = (char *)result16;
|
83
|
-
|
84
84
|
return result;
|
85
85
|
}
|
86
86
|
|
@@ -89,4 +89,22 @@
|
|
89
89
|
}
|
90
90
|
```
|
91
91
|
|
92
|
-
ただpythonオブジェクトへの変換に相当のオーバーヘッドがあるようですね。
|
92
|
+
ただpythonオブジェクトへの変換に相当のオーバーヘッドがあるようですね。
|
93
|
+
|
94
|
+
あと、インターフェースを多少整えました。
|
95
|
+
|
96
|
+
**convmod.py**
|
97
|
+
```python
|
98
|
+
import ctypes
|
99
|
+
|
100
|
+
cptr = ctypes.POINTER(ctypes.c_char)
|
101
|
+
lib = ctypes.cdll.LoadLibrary('./conv.so')
|
102
|
+
lib.convert.restype = cptr
|
103
|
+
lib.convert.argtypes = (ctypes.c_int, cptr)
|
104
|
+
|
105
|
+
def conv(b_input):
|
106
|
+
n = len(b_input)
|
107
|
+
result = lib.convert(n, b_input)[:n]
|
108
|
+
lib.free_result()
|
109
|
+
return result
|
110
|
+
```
|
4
更に追記
answer
CHANGED
@@ -51,11 +51,42 @@
|
|
51
51
|
print(result) # => b'\x01\x00\x03\x02'
|
52
52
|
```
|
53
53
|
|
54
|
-
### 追記
|
54
|
+
### 追記2
|
55
55
|
```python
|
56
56
|
def conv_np(b_input):
|
57
57
|
npa = np.frombuffer(b_input, dtype=np.int16).copy()
|
58
58
|
return npa.byteswap(inplace=True).tobytes()
|
59
59
|
```
|
60
60
|
|
61
|
-
こんなのと速度を比較したら、顕著な速度差がなかったことを申し添えておきます。悲しい。
|
61
|
+
こんなのと速度を比較したら、顕著な速度差がなかったことを申し添えておきます。悲しい。
|
62
|
+
|
63
|
+
### 追記3
|
64
|
+
ビットシフトで書き直して、なんとかnumpyより速くなりました。
|
65
|
+
|
66
|
+
```C
|
67
|
+
#include <stdlib.h>
|
68
|
+
#include <stdint.h>
|
69
|
+
|
70
|
+
char *result;
|
71
|
+
|
72
|
+
char *convert(int n, char *buf){
|
73
|
+
int i, nh;
|
74
|
+
uint16_t *result16, *buf16;
|
75
|
+
|
76
|
+
result16 = (uint16_t *)malloc(sizeof(char)*n);
|
77
|
+
buf16 = (uint16_t *)buf;
|
78
|
+
nh = n/2;
|
79
|
+
for(i=0; i < nh; i++) {
|
80
|
+
result16[i] = buf16[i] >> 8 | buf16[i] << 8;
|
81
|
+
}
|
82
|
+
result = (char *)result16;
|
83
|
+
|
84
|
+
return result;
|
85
|
+
}
|
86
|
+
|
87
|
+
void free_result(void) {
|
88
|
+
free(result);
|
89
|
+
}
|
90
|
+
```
|
91
|
+
|
92
|
+
ただpythonオブジェクトへの変換に相当のオーバーヘッドがあるようですね。
|
3
もう少し追記
answer
CHANGED
@@ -49,4 +49,13 @@
|
|
49
49
|
result = lib.convert(n, b_input)[:n]
|
50
50
|
lib.free_result()
|
51
51
|
print(result) # => b'\x01\x00\x03\x02'
|
52
|
-
```
|
52
|
+
```
|
53
|
+
|
54
|
+
### 追記
|
55
|
+
```python
|
56
|
+
def conv_np(b_input):
|
57
|
+
npa = np.frombuffer(b_input, dtype=np.int16).copy()
|
58
|
+
return npa.byteswap(inplace=True).tobytes()
|
59
|
+
```
|
60
|
+
|
61
|
+
こんなのと速度を比較したら、顕著な速度差がなかったことを申し添えておきます。悲しい。
|
2
メモリ管理
answer
CHANGED
@@ -10,8 +10,9 @@
|
|
10
10
|
```C
|
11
11
|
#include <stdlib.h>
|
12
12
|
|
13
|
+
char *result;
|
14
|
+
|
13
15
|
char *convert(int n, char *buf){
|
14
|
-
char *result;
|
15
16
|
int i;
|
16
17
|
|
17
18
|
result = (char *)malloc(sizeof(char)*n);
|
@@ -23,6 +24,10 @@
|
|
23
24
|
|
24
25
|
return result;
|
25
26
|
}
|
27
|
+
|
28
|
+
void free_result(void) {
|
29
|
+
free(result);
|
30
|
+
}
|
26
31
|
```
|
27
32
|
|
28
33
|
**コンパイルコマンド**
|
@@ -42,6 +47,6 @@
|
|
42
47
|
b_input = b'\x00\x01\x02\x03'
|
43
48
|
n = len(b_input)
|
44
49
|
result = lib.convert(n, b_input)[:n]
|
45
|
-
|
50
|
+
lib.free_result()
|
46
51
|
print(result) # => b'\x01\x00\x03\x02'
|
47
52
|
```
|
1
追記
answer
CHANGED
@@ -1,3 +1,47 @@
|
|
1
1
|
高速性を重視するなら、Cで書いてpythonからwrapして使うというのはどうでしょうか。
|
2
2
|
|
3
|
-
[16.16. ctypes — Pythonのための外部関数ライブラリ — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/ctypes.html)
|
3
|
+
[16.16. ctypes — Pythonのための外部関数ライブラリ — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/ctypes.html)
|
4
|
+
|
5
|
+
|
6
|
+
### 追記
|
7
|
+
書いてみました。私もctypesには慣れていないので、確実な動作は保証しません。変なところがあれば、極力修正はするつもりです。
|
8
|
+
|
9
|
+
**conv.c**
|
10
|
+
```C
|
11
|
+
#include <stdlib.h>
|
12
|
+
|
13
|
+
char *convert(int n, char *buf){
|
14
|
+
char *result;
|
15
|
+
int i;
|
16
|
+
|
17
|
+
result = (char *)malloc(sizeof(char)*n);
|
18
|
+
|
19
|
+
for(i=0; i < n; i+=2) {
|
20
|
+
result[i] = buf[i+1];
|
21
|
+
result[i+1] = buf[i];
|
22
|
+
}
|
23
|
+
|
24
|
+
return result;
|
25
|
+
}
|
26
|
+
```
|
27
|
+
|
28
|
+
**コンパイルコマンド**
|
29
|
+
```
|
30
|
+
$ gcc -shared -fPIC conv.c -o conv.so
|
31
|
+
```
|
32
|
+
|
33
|
+
**conv_test.py**
|
34
|
+
```python
|
35
|
+
import ctypes
|
36
|
+
|
37
|
+
cptr = ctypes.POINTER(ctypes.c_char)
|
38
|
+
lib = ctypes.cdll.LoadLibrary('./conv.so')
|
39
|
+
lib.convert.restype = cptr
|
40
|
+
lib.convert.argtypes = (ctypes.c_int, cptr)
|
41
|
+
|
42
|
+
b_input = b'\x00\x01\x02\x03'
|
43
|
+
n = len(b_input)
|
44
|
+
result = lib.convert(n, b_input)[:n]
|
45
|
+
|
46
|
+
print(result) # => b'\x01\x00\x03\x02'
|
47
|
+
```
|