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