編程小白的隨筆記錄開始啦
先來講講vnr的翻譯速度問題,由于篇幅原因,本章先講translate()函數(shù)調(diào)用形式和優(yōu)化
首先上一個vnr的翻譯函數(shù)調(diào)用棧:
#輸出函數(shù)棧
import inspect
for ins in inspect.stack():
print 'Line = ' + str(ins[2]) + ', Chunk = ' + ins[4][0] + ', Method = ' + ins[3] + ', Path = ' + ins[1]
#函數(shù)棧輸出結(jié)果
Line = 152, Chunk = for ins in inspect.stack():
, Method = translate, Path = py/apps/reader\../../../py/libs\baidu\baidufanyi.py
Line = 409, Chunk = ret = skthreads.runsync(task, abortSignal=self.abortSignal) if async and self.asyncSupported else task()
, Method = _translateTransaction, Path = py/apps/reader\../../../py/apps/reader/managers\_trman.py
Line = 493, Chunk = text = self._cache.get(text) or self._translateTransaction(text, tr, to, fr, async, keepsNewLine)
, Method = _splitTranslate, Path = py/apps/reader\../../../py/apps/reader/managers\_trman.py
Line = 580, Chunk = l = split(text, tr, to, fr, async, keepsNewLine)
, Method = _translate, Path = py/apps/reader\../../../py/apps/reader/managers\_trman.py
Line = 2346, Chunk = to, fr, async, keepsNewLine, align=align)
, Method = translate, Path = py/apps/reader\../../../py/apps/reader/managers\_trman.py
Line = 339, Chunk = r = tr(text, align=align, **kwargs)
, Method = translateAndApply, Path = py/apps/reader\../../../py/apps/reader/managers\trman.py
Line = 78, Chunk = return super(Application, self).notify(receiver, event)
, Method = notify, Path = py/apps/reader\app.py
Line = 78, Chunk = return super(Application, self).notify(receiver, event)
, Method = notify, Path = py/apps/reader\app.py
Line = 418, Chunk = returnCode = a.exec_()
, Method = main, Path = E:\shiyan\Visual Novel Reader\Library\Frameworks\Sakura\py\apps\reader\__main__.py
Line = 825, Chunk = ret = main()
, Method = <module>, Path = E:\shiyan\Visual Novel Reader\Library\Frameworks\Sakura\py\apps\reader\__main__.py
Line = 72, Chunk = exec code in run_globals
, Method = _run_code, Path = E:\shiyan\Visual Novel Reader\Library\Frameworks\Python\lib\runpy.py
Line = 174, Chunk = "__main__", fname, loader, pkg_name)
, Method = _run_module_as_main, Path = E:\shiyan\Visual Novel Reader\Library\Frameworks\Python\lib\runpy.py
從調(diào)用??梢钥闯?,在棧頂是我們的輸出函數(shù),往下是一個
ret = skthreads.runsync(task, abortSignal=self.abortSignal) if async and self.asyncSupported else task()
但顯然在這語塊中并沒用出現(xiàn)我們的translate()函數(shù),我們看看代碼:

第一行的if判斷是做字符串處理,我們后面再講,我們看最后一行,是具體調(diào)用translate()函數(shù)進(jìn)行翻譯的地方,translate()在這是偏函數(shù)調(diào)用,所以先不管后邊三元運算符是怎么判斷的,我們直接進(jìn)去看函數(shù)

函數(shù)一開頭就有介紹:
Run in another thread, and then block and wait for return result
(在另一個線程中運行,然后阻塞并等待返回結(jié)果)
從翻譯的結(jié)果返回就可以看的出來,說是在另一個線程中運行,但其實還是單例運行:

我們在翻譯之前加一句時間輸出:

輸出結(jié)果為:

SKProfiler給我們提供了時間記錄,很詳細(xì)
我們來看看函數(shù)的調(diào)用順序,若是并發(fā)操作,那么三個時間肯定要比翻譯結(jié)果先輸出
所以我們得出了拖慢翻譯速度的原因:單例
試想,原本是一份文本,四個翻譯,需要單例翻譯四次,一次0.25秒,總和1秒
若是字符串里有4個空格類的字符,那么就要分成四份,四個翻譯,單例翻譯總和4*4=16次
也就是4秒的時間,拖慢了四倍,翻譯質(zhì)量也不見得能提高多少
上圖的skevents.waitsignal()函數(shù),實際上是堵塞了主線程,而不是新建的IO線程
但即使我們把這句注釋,仍是單例運行
這里就是python2.7的鍋了,pyqt和pyside里的QThread,也是受GIL影響的,不推薦在IO密集時使用多線程,因為會比單線程效率還要低(但在python3.4以上就能正常使用多線程)
所以在這,我們應(yīng)該修改為真正的多線程并發(fā)請求
——————————————————————————————————————
—————————————————分割線——————————————————
——————————————————————————————————————
下面給出IO密集時,單線程與多線程的對比
代碼對比
#計算1-1000000累加和
class MyThread1(threading.Thread):
def __init__(self):
super(MyThread1, self).__init__()
def run(self):
start = time.time()
i = 0
for ins in range(1000000):
i += ins
print (time.time() - start)
class MyThread2(threading.Thread):
def __init__(self):
super(MyThread2, self).__init__()
def run(self):
start = time.time()
i = 0
for ins in range(1000000):
i += ins
print (time.time() - start)
class MyThread3(threading.Thread):
def __init__(self):
super(MyThread3, self).__init__()
def run(self):
start = time.time()
i = 0
for ins in range(1000000):
i += ins
print (time.time() - start)
if __name__ == "__main__":
start = time.time()
t1 = MyThread1()
t2 = MyThread2()
t3 = MyThread3()
t1.start()
t2.start()
t3.start()
計算時間:

if __name__ == "__main__":
start = time.time()
for ip in range(3):
i = 0
for ins in range(1000000):
i += ins
print (time.time() - start)
計算時間:

IO密集時不推薦,但是IO等待時可以用多線程
例如time.sleep(),以及在網(wǎng)絡(luò)請求等待時,都可以使用
s = u"高校一年生の桜庭理沙は平均的な少女。 ある日拾ったカードの力により魔法少女となり戦うお話"
class MyThread1(threading.Thread):
def __init__(self):
super(MyThread1, self).__init__()
def run(self):
for ins in range(6):
start = time.time()
print ('caiyun : ' + caiyunfanyi.translate(s))
print (time.time() - start)
class MyThread2(threading.Thread):
def __init__(self):
super(MyThread2, self).__init__()
def run(self):
for ins in range(6):
start = time.time()
print ('tengxun : ' + tengxunfanyi.translate(s))
print (time.time() - start)
class MyThread3(threading.Thread):
def __init__(self):
super(MyThread3, self).__init__()
def run(self):
for ins in range(6):
start = time.time()
print ('youdao : ' + youdaozhiyun.translate(s))
print (time.time() - start)
if __name__ == "__main__":
start = time.time()
t1 = MyThread1()
t2 = MyThread2()
t3 = MyThread3()
t1.start()
t2.start()
t3.start()
print (time.time() - start)
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.542000055313
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.593000173569
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.634999990463
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.203000068665
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.228999853134
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.303000211716
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.213999986649
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.230999946594
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.131999969482
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.208999872208
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.125
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.239000082016
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.128000020981
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.203999996185
tengxun : 高中一年級的櫻庭理沙是平均的少女。某天用撿到的卡片的力量成為魔法少女戰(zhàn)斗的故事
0.138000011444
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.240000009537
caiyun : 高中一年級的櫻庭理沙是個普通的少女。 一個故事講述了一個女巫和一個魔法女孩在一張卡片上戰(zhàn)斗的故事
0.203000068665
youdao : 高中一年級的櫻庭理沙是個普通少女。根據(jù)某天撿到的卡的力量成為魔法少女戰(zhàn)斗的故事
0.240999937057
第一個請求需要初始化,所以比較慢
從上面可以看出,在python2.7中,網(wǎng)絡(luò)請求也可以進(jìn)行并發(fā)操作、
但是不能使用requests作為網(wǎng)絡(luò)請求庫,requests是一個同步庫,異步網(wǎng)上貌似都推薦aiohttp,但我查了查,aiohttp最低支持python3.4,python2.7明顯不能用
所以只能另辟蹊徑,使用urllib+urllib2作為網(wǎng)絡(luò)請求庫
翻譯流程優(yōu)化的第一步先記錄到這里