作者查詢 / LiloHuang

總覽項目: 發文 | 留言 | 暱稱
作者 LiloHuang 在 PTT [ Python ] 看板的留言(推文), 共373則
限定看板:Python
[問題] 想請問有更有效率的寫法嗎?
[ Python ]18 留言, 推噓總分: +2
作者: sariel0322 - 發表於 2014/08/24 14:05(11年前)
1FLiloHuang: 如果重複的資料很多,應該可以不用先把資料放到list內08/24 17:02
2FLiloHuang: 提供一個做法也許不見得會變快 XD08/24 17:03
3FLiloHuang: import csv08/24 17:04
4FLiloHuang: uniqueSet = set()08/24 17:04
5FLiloHuang: o = open("output.csv","w")08/24 17:04
6FLiloHuang: f = open("input.csv","r")08/24 17:04
7FLiloHuang: for row in csv.reader(f):08/24 17:04
8FLiloHuang: line = ",".join(row)08/24 17:04
9FLiloHuang: if line not in uniqueSet:08/24 17:05
10FLiloHuang: o.write(line + "\n")08/24 17:05
11FLiloHuang: uniqueSet.add(line)08/24 17:05
12FLiloHuang: f.close()08/24 17:05
13FLiloHuang: o.close()08/24 17:05
14FLiloHuang: 有時候性能瓶頸是在硬碟本身,可以看看 CPU 是否有吃滿08/24 17:11
15FLiloHuang: 畢竟 400mb 的 CSV 要跑到五天真的有點久了些...08/24 17:12
16FLiloHuang: 避免先放到 list 再轉,至少可以省掉一次 O(n) 的浪費08/24 17:19
18FLiloHuang: 推 yjcl 的做法,雖然會動到資料先後順序,但非常優雅!08/24 21:10
[問題] 停止正在執行 3rd party lib 的 thread
[ Python ]45 留言, 推噓總分: +6
作者: carylorrk - 發表於 2014/08/22 10:03(11年前)
1FLiloHuang: 我想先說明,終止線程跟 OS 本身有極高的相關性08/22 20:45
2FLiloHuang: 我印象中目前並無某種方法,或某個內建的 API08/22 20:45
3FLiloHuang: 可以保證的在所有的系統上,終止某個特定線程。08/22 20:46
4FLiloHuang: 至少 Win32 得用 TerminateThread,不同於 pthread08/22 20:46
5FLiloHuang: 我先假設你所使用的作業系統所操作的是 pthread08/22 20:46
6FLiloHuang: 無論是透過 get_ident 或用 ident 都是拿到 pthread_t08/22 20:46
7FLiloHuang: 也就是 pthread_self() 會拿到的內容 (可查源碼參照)08/22 20:46
8FLiloHuang: 你拿到的數值會有點大,我猜你的系統應該是 64 bit08/22 20:46
9FLiloHuang: StackOverflow 那則被打勾的回應是常見的好方法08/22 20:47
10FLiloHuang: 至少這個方式不是真正強制硬砍掉 Thread 運行08/22 20:47
11FLiloHuang: 然而之所以你會拿到 invalid thread ID 的原因是08/22 20:47
12FLiloHuang: 你得改所有用到 PyThreadState_SetAsyncExc 的部分08/22 20:47
13FLiloHuang: foobar = ctypes.pythonapi.PyThreadState_SetAsyncExc08/22 20:47
14FLiloHuang: foobar.argtypes = [ctypes.c_long, ctypes.py_object]08/22 20:47
15FLiloHuang: res = foobar(tid, ctypes.py_object(exctype))08/22 20:48
16FLiloHuang: 請把原文章中的 _async_raise 前幾行,適度修改如上08/22 20:48
17FLiloHuang: 如此一來就應該不會出現 invalid thread ID 的狀況08/22 20:49
18FLiloHuang: 原因是在 64 bit 的環境中,得寫清楚帶進去的資料型態08/22 20:50
19FLiloHuang: 再透過 _async_raise(thr.ident, RuntimeError) 來終止08/22 20:51
20FLiloHuang: 至於是否有更好的做法? 可以開 child process 也是一種08/22 20:53
21FLiloHuang: 可以把傷害擺到另外一個進程,儘管還是會有機率出狀況08/22 20:55
22FLiloHuang: 最好的方式是改 3rd party lib 使其 graceful exit :D08/22 20:55
23FLiloHuang: 行有餘力還可以順便 merge 回 master/trunk 之類的 XD08/22 20:57
24FLiloHuang: 其實我也沒仔細看所有回應,只是要說 ctypes 在 64bit08/23 00:14
25FLiloHuang: 的環境得多設定 argtypes 或者直接類似該討論串中某篇08/23 00:15
26FLiloHuang: 直接生出 c_long(tid) 再進行帶入的動作...08/23 00:15
27FLiloHuang: 最好的方式就是用 event / mutex 實作 graceful exit08/23 00:15
28FLiloHuang: 或者用一個 atomic variable 來當作 stop flag 之類的08/23 00:16
29FLiloHuang: 畢竟沒看到 3rd party lib 的原始碼,我只能猜到這 XD08/23 00:18
30FLiloHuang: 至於 Python 還有個 GIL,如果用一些強制力砍掉 thread08/23 00:21
31FLiloHuang: 如果剛好被砍掉的 thread 是持有 GIL 的話,那就有趣了08/23 00:21
32FLiloHuang: 如果是 mission critical 的環境,就得考量更多的細節08/23 00:23
33FLiloHuang: 總之恭喜你有把問題解決囉 :D08/23 00:24
34FLiloHuang: 畢竟提及 child process 只是想避掉 GIL 這個老問題08/23 00:27
35FLiloHuang: 不應該有GIL的問題,誠如我一開始提到這不是強制砍掉它08/23 01:35
36FLiloHuang: 所謂的強制力是指 pthread_kill or TerminateThread08/23 01:37
37FLiloHuang: 然而如果能實作 graceful exit 還是最好的方向就是 :)08/23 01:38
38FLiloHuang: 因為 PyThreadState_SetAsyncExc 是請求觸發 exception08/23 01:58
39FLiloHuang: 並不會真的立刻把該 thread 給終止掉,聽起來雖然不錯08/23 01:59
40FLiloHuang: 然而如果該 thread 不幸卡在一個很久的 blocking I/O08/23 02:01
41FLiloHuang: 或者該 thread 剛好操作某個會卡很久的 C-API08/23 02:02
42FLiloHuang: 就不一定能如同原本預期,順利的把 thread 給終止掉了08/23 02:03
43FLiloHuang: 畢竟這個的原理是在 PyEval_EvalFrameEx 還沒跑 opcode08/23 02:05
44FLiloHuang: 之前進行檢查 tstate->async_exc 的值是否有被設定 :D08/23 02:05
45FLiloHuang: 可參考源碼瞭解更多細節http://goo.gl/878eMi 大概如此08/23 02:07
[問題] 請教處理ctypes dll 回傳 c_ubyte_p 問題
[ Python ]41 留言, 推噓總分: +5
作者: dctzeng - 發表於 2014/08/14 23:05(11年前)
1FLiloHuang: 如果要在 Python 內操作資料,資料通常都得做搬動的08/14 23:35
2FLiloHuang: 我猜你應該是想要做以下的事情...我先把問題簡化08/14 23:35
3FLiloHuang: 假設使用 addr = ctypes.cdll.msvcrt.malloc(1024)08/14 23:36
4FLiloHuang: 得到一個記憶體位置為 addr,類似你的GetBufferAddress08/14 23:36
5FLiloHuang: 如果我先用 memmove(addr, "\xFF\xFF\x00\x00", 4)08/14 23:36
6FLiloHuang: 此時應該會寫入 4 byte 的資料,考慮 little endian08/14 23:37
7FLiloHuang: cast(x, POINTER(c_int)).contents.value 會讀出 6553508/14 23:37
8FLiloHuang: 抱歉上面的 x 是指 addr 的意思,推文實在塞不下08/14 23:38
9FLiloHuang: 再次更正 x = c_void_p(addr)08/14 23:39
10FLiloHuang: 使用 c_void_p(addr) 的方式將你的指標塞進去後08/14 23:40
11FLiloHuang: 就可以用 cast 搭配 contents.value 的方式來做存取了08/14 23:41
13FLiloHuang: 這樣記憶體就是由 Python runtime 幫你管理08/14 23:44
15FLiloHuang: 至於拷貝看是拷貝什麼,畢竟很多東西都得變 PyObject08/14 23:44
16FLiloHuang: 可以的呀,正常操作狀況不會一直拷貝那 1MB 的08/14 23:45
19FLiloHuang: 你可以看看 byref, addressof, cast 這幾個的用法08/14 23:47
20FLiloHuang: 資料從 Python 跟 C API 做交換,ctypes 會有一些成本08/14 23:48
22FLiloHuang: 當你東西是使用指標 (也就是我上面的範例) 算快的做法08/14 23:48
23FLiloHuang: 如果是我寫我會盡量讓 Python runtime 來幫我管記憶體08/14 23:49
24FLiloHuang: 當然還是得看場合,到底是誰該擺那一塊記憶體...08/14 23:51
25FLiloHuang: 好比說用 create_string_buffer 來產生 buffer object08/14 23:52
27FLiloHuang: 不好意思我現在看到你修改後的文章了...08/14 23:55
29FLiloHuang: 那我重新修正,如果你只是想要比較用 c_char_p 就好08/15 00:08
30FLiloHuang: foo = 'x'*1024*1024*100 # 記憶體耗用 100 MB 左右08/15 00:09
31FLiloHuang: bar = c_char_p(foo) # 這個動作不會拷貝 100MB08/15 00:09
32FLiloHuang: ctypes.memmove(bar, "test", 4) # 硬是修改 foo 字串08/15 00:09
33FLiloHuang: # 雷同於你傳入 DLL08/15 00:10
34FLiloHuang: print foo[0:10] # 順便再印出 foo 的一部分觀察08/15 00:10
35FLiloHuang: 以上的 foo 類似於你從 fd.read 讀出的字串結果08/15 00:11
36FLiloHuang: ctypes.memmove 類似於你帶入 DLL 的部分,試試看囉08/15 00:12
37FLiloHuang: 可搭配 ProcessExplorer 選 python.exe 觀察記憶體用量08/15 00:14
38FLiloHuang: 順便回你文章的那個問題,那個寫法應該也不會拷貝資料08/15 00:41
39FLiloHuang: 至於之所以會出錯的原因是 from_address 是吃 integer08/15 00:42
40FLiloHuang: 用了 hex 就變成了字串,錯誤訊息是指參數型別不正確08/15 00:43
41FLiloHuang: 這種做法也是拿一個指標來操作的做法,都相當的快速08/15 00:44
[問題] 讀檔如何避開OS cache or buffer?
[ Python ]49 留言, 推噓總分: +10
作者: dctzeng - 發表於 2014/08/12 20:25(11年前)
1FLiloHuang: 恐怕得直接用 ctypes 或者 pywin32 呼叫 CreateFileW08/12 20:45
2FLiloHuang: 搭配FILE_FLAG_WRITE_THROUGH, FILE_FLAG_NO_BUFFERING08/12 20:46
3FLiloHuang: 我剛瞧了一下 Python 2.7 的源碼,並無以上的實作釋出08/12 20:47
4FLiloHuang: 順便附上 MSDN 重要的說明片段,http://goo.gl/pc4Dlt08/12 20:48
6FLiloHuang: 剛剛看到有一條路可以用...應該算是隱藏的後門 XD08/12 20:55
7FLiloHuang: from _multiprocessing import win32 之後08/12 20:55
8FLiloHuang: 就可以用 win32.CreateFile(...) 的 API 來設定 flag08/12 20:56
9FLiloHuang: 可參照 Python 官網原始碼來操作 http://goo.gl/xNBXVh08/12 21:02
10FLiloHuang: 只不過上面兩個常數沒有被寫進去,得查 header file 囉08/12 21:03
13FLiloHuang: 真尷尬,剛剛去看了一下 DLLs\_multiprocessing.pyd08/12 22:07
14FLiloHuang: 該檔案的 Win32 PE Import Table 是寫 CreateFileA08/12 22:09
15FLiloHuang: 猜測 CPython 2.7 當初編譯時,沒有用 UNICODE 來編譯08/12 22:10
16FLiloHuang: 只能請樓主用 ctypes.windll.kernel32.CreateFileW 囉08/12 22:10
17FLiloHuang: 不然就只能用 win32.CreateFile(r'D:\中文字.txt', ...08/12 22:23
18FLiloHuang: Non-UNICODE 版本加減用 XD 只是這樣不是很好就是08/12 22:24
19FLiloHuang: 補充如果要自己重新編譯 Python Runtime 使其支援 XD08/12 22:37
20FLiloHuang: 除了得選 UNICODE 模式,PyArg_ParseTuple 也得改一下08/12 22:38
21FLiloHuang: 但是這不是一個很正常的方式,跟官方版本一致就好08/12 22:40
28FLiloHuang: 基本上呢該篇文章就是我第一個回應提到的,使用pywin3208/13 23:43
29FLiloHuang: 如果樓主願意安裝pywin32的話,那是一個很棒的選擇 :D08/13 23:43
30FLiloHuang: 至於 fd.flush 實作原始碼在這邊 http://goo.gl/uirMHF08/13 23:44
31FLiloHuang: 根據原始碼 file_flush 的實作,是使用 fflush 函式08/13 23:46
32FLiloHuang: fflush 是標準 C runtime 提供的能力,而呼叫 fflush08/13 23:46
33FLiloHuang: 並不會呼叫 Win32 API 的 FlushFileBuffers08/13 23:47
34FLiloHuang: 樓主也可以用 windbg 下中斷點測試 :D 應該不會hit才是08/13 23:48
35FLiloHuang: 畢竟 fflush 跟 FlushFileBuffers 使用的目的就不同08/13 23:51
36FLiloHuang: 而在這個狀況的確得使用 FlushFileBuffers 再搭配08/13 23:51
37FLiloHuang: 我先前的推文或該文章中所提及的那兩個 flag 才是正解08/13 23:53
38FLiloHuang: 然而 os.fsync 狀況就不同了,在視窗平台上會用_commit08/14 00:04
39FLiloHuang: _commit 會轉呼叫 FlushFileBuffers (可下斷點驗證)08/14 00:04
40FLiloHuang: 根據以上資訊 os.fsync 應該要清緩衝,也許可以再試試08/14 00:08
41FLiloHuang: 當然使用時,你的 fd 本身在建立時也得具備那兩個 flag08/14 00:09
43FLiloHuang: 關於 fd.flush 這才是對的版本 http://goo.gl/LQ6Wel08/14 23:05
44FLiloHuang: 上面那個連結我貼成 stackless 版,儘管內容幾乎一樣08/14 23:05
45FLiloHuang: 至於怎麼樣找原始碼? 官網就有提供下載整包源碼啦 :D08/14 23:06
46FLiloHuang: trunk 在這 http://svn.python.org/projects/trunk/08/14 23:07
47FLiloHuang: http://svn.python.org/projects/python/trunk/ 更正..08/14 23:08
48FLiloHuang: 要看特定版號就去官網首頁抓源碼,或在SVN找對應branch08/14 23:11
[問題] 請問API該如何查?
[ Python ]5 留言, 推噓總分: +3
作者: dcleft - 發表於 2014/08/12 19:41(11年前)
3FLiloHuang: int.from_bytes() 得看 Python 3 http://goo.gl/PFNqoD08/12 23:57
[問題] 錯誤?
[ Python ]3 留言, 推噓總分: +3
作者: ghkckhg - 發表於 2014/08/06 19:40(11年前)
1FLiloHuang:你是用 Python with Braces 嗎 XD 不然怎會有大括號出現08/06 20:19
[問題] python 速度 FOR_LOOP
[ Python ]27 留言, 推噓總分: +14
作者: redonizuka - 發表於 2014/08/05 00:27(11年前)
13FLiloHuang:它會編譯成 bytecode 來跑呀,只是 CPython 挺慢是事實08/06 20:27
14FLiloHuang:現階段 CPython 也沒有像 Java 或 .NET 有做 JIT 優化08/06 20:28
15FLiloHuang:迴圈自然就是不會快去哪邊,做 Convolution 用 GPU 最快08/06 20:29
16FLiloHuang:退而求其次就是用 numpy.convolve + numpy.absolute08/06 20:33
17FLiloHuang:NumbaPro 聽說挺不錯的,可以用到 GPU 來加速...08/06 20:35
18FLiloHuang:另外,Sobel filter 是 separable filter 我想你知道 :D08/06 22:19
19FLiloHuang:儘管從 2D kernel 改 1D kernel 對於 Python 也沒快很多08/06 22:20
20FLiloHuang:這個 http://goo.gl/CrQiXl 可以跑跑看,也許有幫助 :P08/06 22:48
22FLiloHuang:社群版的 Numba 效果應該也不錯吧,NumbaPro 得花錢就是08/08 09:28
Re: [問題] python or perl?已刪文
[ Python ]17 留言, 推噓總分: +12
作者: Neisseria - 發表於 2014/07/07 14:03(11年前)
13FLiloHuang:CindyLinz 都出現了,實在得推一下 Perl :D07/17 23:16
14FLiloHuang:個人認為兩種語言都值得學習,久了自然會有一些心得 :)07/17 23:22
[問題] 如何計算影像的線段長度
[ Python ]7 留言, 推噓總分: +3
作者: ryoma0915 - 發表於 2014/05/15 18:29(11年前)
1FLiloHuang:我想到用 Hough transform 偵測直線,再把線段加總起來05/15 20:22
2FLiloHuang:OpenCV 的 Python bindings 找找看應該有類似的實作05/15 20:23
[問題] 純文件中的\uxxxx想直接轉成UTF-8顯示
[ Python ]4 留言, 推噓總分: +2
作者: ptero - 發表於 2014/05/08 15:38(12年前)
1FLiloHuang:print "\\u860b\\u679c".decode("unicode_escape")05/08 15:50
3FLiloHuang:codecs.open("in.txt", "r", "unicode_escape").read()05/08 15:55