回答編集履歴

5

追記

2018/10/19 18:37

投稿

hayataka2049
hayataka2049

スコア30933

test CHANGED
@@ -160,10 +160,10 @@
160
160
 
161
161
  }
162
162
 
163
+
164
+
163
165
  result = (char *)result16;
164
166
 
165
-
166
-
167
167
  return result;
168
168
 
169
169
  }
@@ -181,3 +181,39 @@
181
181
 
182
182
 
183
183
  ただpythonオブジェクトへの変換に相当のオーバーヘッドがあるようですね。
184
+
185
+
186
+
187
+ あと、インターフェースを多少整えました。
188
+
189
+
190
+
191
+ **convmod.py**
192
+
193
+ ```python
194
+
195
+ import ctypes
196
+
197
+
198
+
199
+ cptr = ctypes.POINTER(ctypes.c_char)
200
+
201
+ lib = ctypes.cdll.LoadLibrary('./conv.so')
202
+
203
+ lib.convert.restype = cptr
204
+
205
+ lib.convert.argtypes = (ctypes.c_int, cptr)
206
+
207
+
208
+
209
+ def conv(b_input):
210
+
211
+ n = len(b_input)
212
+
213
+ result = lib.convert(n, b_input)[:n]
214
+
215
+ lib.free_result()
216
+
217
+ return result
218
+
219
+ ```

4

更に追記

2018/10/19 18:37

投稿

hayataka2049
hayataka2049

スコア30933

test CHANGED
@@ -104,7 +104,7 @@
104
104
 
105
105
 
106
106
 
107
- ### 追記
107
+ ### 追記2
108
108
 
109
109
  ```python
110
110
 
@@ -119,3 +119,65 @@
119
119
 
120
120
 
121
121
  こんなのと速度を比較したら、顕著な速度差がなかったことを申し添えておきます。悲しい。
122
+
123
+
124
+
125
+ ### 追記3
126
+
127
+ ビットシフトで書き直して、なんとかnumpyより速くなりました。
128
+
129
+
130
+
131
+ ```C
132
+
133
+ #include <stdlib.h>
134
+
135
+ #include <stdint.h>
136
+
137
+
138
+
139
+ char *result;
140
+
141
+
142
+
143
+ char *convert(int n, char *buf){
144
+
145
+ int i, nh;
146
+
147
+ uint16_t *result16, *buf16;
148
+
149
+
150
+
151
+ result16 = (uint16_t *)malloc(sizeof(char)*n);
152
+
153
+ buf16 = (uint16_t *)buf;
154
+
155
+ nh = n/2;
156
+
157
+ for(i=0; i < nh; i++) {
158
+
159
+ result16[i] = buf16[i] >> 8 | buf16[i] << 8;
160
+
161
+ }
162
+
163
+ result = (char *)result16;
164
+
165
+
166
+
167
+ return result;
168
+
169
+ }
170
+
171
+
172
+
173
+ void free_result(void) {
174
+
175
+ free(result);
176
+
177
+ }
178
+
179
+ ```
180
+
181
+
182
+
183
+ ただpythonオブジェクトへの変換に相当のオーバーヘッドがあるようですね。

3

もう少し追記

2018/10/19 18:27

投稿

hayataka2049
hayataka2049

スコア30933

test CHANGED
@@ -101,3 +101,21 @@
101
101
  print(result) # => b'\x01\x00\x03\x02'
102
102
 
103
103
  ```
104
+
105
+
106
+
107
+ ### 追記
108
+
109
+ ```python
110
+
111
+ def conv_np(b_input):
112
+
113
+ npa = np.frombuffer(b_input, dtype=np.int16).copy()
114
+
115
+ return npa.byteswap(inplace=True).tobytes()
116
+
117
+ ```
118
+
119
+
120
+
121
+ こんなのと速度を比較したら、顕著な速度差がなかったことを申し添えておきます。悲しい。

2

メモリ管理

2018/10/19 17:31

投稿

hayataka2049
hayataka2049

スコア30933

test CHANGED
@@ -22,9 +22,11 @@
22
22
 
23
23
 
24
24
 
25
+ char *result;
26
+
27
+
28
+
25
29
  char *convert(int n, char *buf){
26
-
27
- char *result;
28
30
 
29
31
  int i;
30
32
 
@@ -45,6 +47,14 @@
45
47
 
46
48
 
47
49
  return result;
50
+
51
+ }
52
+
53
+
54
+
55
+ void free_result(void) {
56
+
57
+ free(result);
48
58
 
49
59
  }
50
60
 
@@ -86,7 +96,7 @@
86
96
 
87
97
  result = lib.convert(n, b_input)[:n]
88
98
 
89
-
99
+ lib.free_result()
90
100
 
91
101
  print(result) # => b'\x01\x00\x03\x02'
92
102
 

1

追記

2018/10/19 16:29

投稿

hayataka2049
hayataka2049

スコア30933

test CHANGED
@@ -3,3 +3,91 @@
3
3
 
4
4
 
5
5
  [16.16. ctypes — Pythonのための外部関数ライブラリ — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/ctypes.html)
6
+
7
+
8
+
9
+
10
+
11
+ ### 追記
12
+
13
+ 書いてみました。私もctypesには慣れていないので、確実な動作は保証しません。変なところがあれば、極力修正はするつもりです。
14
+
15
+
16
+
17
+ **conv.c**
18
+
19
+ ```C
20
+
21
+ #include <stdlib.h>
22
+
23
+
24
+
25
+ char *convert(int n, char *buf){
26
+
27
+ char *result;
28
+
29
+ int i;
30
+
31
+
32
+
33
+ result = (char *)malloc(sizeof(char)*n);
34
+
35
+
36
+
37
+ for(i=0; i < n; i+=2) {
38
+
39
+ result[i] = buf[i+1];
40
+
41
+ result[i+1] = buf[i];
42
+
43
+ }
44
+
45
+
46
+
47
+ return result;
48
+
49
+ }
50
+
51
+ ```
52
+
53
+
54
+
55
+ **コンパイルコマンド**
56
+
57
+ ```
58
+
59
+ $ gcc -shared -fPIC conv.c -o conv.so
60
+
61
+ ```
62
+
63
+
64
+
65
+ **conv_test.py**
66
+
67
+ ```python
68
+
69
+ import ctypes
70
+
71
+
72
+
73
+ cptr = ctypes.POINTER(ctypes.c_char)
74
+
75
+ lib = ctypes.cdll.LoadLibrary('./conv.so')
76
+
77
+ lib.convert.restype = cptr
78
+
79
+ lib.convert.argtypes = (ctypes.c_int, cptr)
80
+
81
+
82
+
83
+ b_input = b'\x00\x01\x02\x03'
84
+
85
+ n = len(b_input)
86
+
87
+ result = lib.convert(n, b_input)[:n]
88
+
89
+
90
+
91
+ print(result) # => b'\x01\x00\x03\x02'
92
+
93
+ ```