[英]Make the program run faster
我編寫了一個程序來檢查文本文檔中的詛咒詞。 我將文檔轉換為單詞列表並將每個單詞傳遞給站點以檢查它是否是詛咒詞。 問題是如果文本太大,它運行很慢。 我如何讓它更快?
import urllib.request
def read_text():
quotes = open(r"C:\Self\General\Pooja\Edu_Career\Learning\Python\Code\Udacity_prog_foundn_python\movie_quotes.txt") #built in function
contents_of_file = quotes.read().split()
#print(contents_of_file)
quotes.close()
check_profanity(contents_of_file)
def check_profanity(text_to_check):
flag = 0
for word in text_to_check:
connection = urllib.request.urlopen("http://www.wdylike.appspot.com/?q="+word)
output = connection.read()
# print(output)
if b"true" in output: # file is opened in bytes mode and output is in byte so compare byte to byte
flag= flag +1
if flag > 0:
print("profanity alert")
else:
print("the text has no curse words")
connection.close()
read_text()
您正在使用的網站支持每次獲取多個單詞。 因此,為了使您的代碼更快: A) 當您找到第一個詛咒詞時打破循環。 B) 發送超級詞到站點。 因此:
def check_profanity(text_to_check):
flag = 0
super_word = ''
for i in range(len(text_to_check)):
if i < 100 and i < len(text_to_check): #100 or max number of words you can check at the same time
super_word = super_word + " " + word
else:
connection = urllib.request.urlopen("http://www.wdylike.appspot.com/?q="+super_word)
super_word = ''
output = connection.read()
if b"true" in output:
flag = flag +1
break
if flag > 0:
print("profanity alert")
else:
print("the text has no curse words")
首先,正如Menno Van Dijk 所建議的那樣,在本地存儲一個常見的詛咒詞子集將允許預先快速檢查臟話,根本不需要查詢網站; 如果發現已知的詛咒詞,您可以立即發出警報,而無需檢查任何其他內容。
其次,反轉該建議,在本地緩存至少前幾千個最常見的已知非詛咒詞; 沒有理由每次包含“is”、“the”或“a”這個詞的文本都應該一遍又一遍地重新檢查這些詞。 由於絕大多數書面英語主要使用兩千個最常用的單詞(甚至更多的人幾乎只使用一萬個最常用的單詞),因此可以節省大量檢查。
第三,在檢查之前統一你的話; 如果一個詞被重復使用,第二次和第一次一樣好或壞,所以檢查兩次是浪費。
最后,正如MTMD 建議的那樣,該站點允許您批量查詢,所以請這樣做。
在所有這些建議中,您可能會從需要 100,000 個連接的 100,000 字文件變為僅需要 1-2 個連接。 雖然多線程可能對您的原始代碼有所幫助(以破壞web 服務為代價),但這些修復應該使多線程毫無意義; 只有 1-2 個請求,您可以等待它們按順序運行所需的第二或兩個。
作為一個純粹的風格問題,具有read_text
呼叫check_profanity
是奇數; 那些真正應該單獨行為( read_text
返回文本其check_profanity
然后可以叫上)。
根據我的建議(假設存在每行一個已知單詞,一個表示壞詞,一個表示好詞的文件):
import itertools # For islice, useful for batching
import urllib.request
def load_known_words(filename):
with open(filename) as f:
return frozenset(map(str.rstrip, f))
known_bad_words = load_known_words(r"C:\path\to\knownbadwords.txt")
known_good_words = load_known_words(r"C:\path\to\knowngoodwords.txt")
def read_text():
with open(r"C:\Self\General\Pooja\Edu_Career\Learning\Python\Code\Udacity_prog_foundn_python\movie_quotes.txt") as quotes:
return quotes.read()
def check_profanity(text_to_check):
# Uniquify contents so words aren't checked repeatedly
if not isinstance(text_to_check, (set, frozenset)):
text_to_check = set(text_to_check)
# Remove words known to be fine from set to check
text_to_check -= known_good_words
# Precheck for any known bad words so loop is skipped completely if found
has_profanity = not known_bad_words.isdisjoint(text_to_check)
while not has_profanity and text_to_check:
block_to_check = frozenset(itertools.islice(text_to_check, 100))
text_to_check -= block_to_check
with urllib.request.urlopen("http://www.wdylike.appspot.com/?q="+' '.join(block_to_check)) as connection:
output = connection.read()
# print(output)
has_profanity = b"true" in output
if has_profanity:
print("profanity alert")
else:
print("the text has no curse words")
text = read_text()
check_profanity(text.split())
您可以執行以下操作:
使用多線程。
批量閱讀文本。
將每個批次分配給一個線程並分別檢查所有批次。
一次發送很多字。 將 number_of_words 更改為您要一次發送的字數。
import urllib.request
def read_text():
quotes = open("test.txt")
contents_of_file = quotes.read().split()
quotes.close()
check_profanity(contents_of_file)
def check_profanity(text):
number_of_words = 200
word_lists = [text[x:x+number_of_words] for x in range(0, len(text), number_of_words)]
flag = False
for word_list in word_lists:
connection = urllib.request.urlopen("http://www.wdylike.appspot.com/?q=" + "%20".join(word_list))
output = connection.read()
if b"true" in output:
flag = True
break
connection.close()
if flag:
print("profanity alert")
else:
print("the text has no curse words")
read_text()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.