vnr研究記錄(一)

編程小白的隨筆記錄開始啦
先來講講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ù),我們看看代碼:

上面用了偏函數(shù)

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

runsync()

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

其實還是單例運行

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

dprint(time())

輸出結(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)化的第一步先記錄到這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容