Skip to content

Commit 37726f3

Browse files
authored
Merge pull request #1182 from PyThaiNLP/copilot/improve-pythainlp-performance
Optimize Python performance: eliminate anti-patterns in loops, collections, string operations, data structures, and memory usage
2 parents f59b908 + 08092b2 commit 37726f3

21 files changed

Lines changed: 827 additions & 814 deletions

File tree

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.12
1+
3.9

pythainlp/ancient/aksonhan.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# SPDX-License-Identifier: Apache-2.0
44
from __future__ import annotations
55

6+
from itertools import chain
7+
68
from pythainlp import thai_consonants, thai_tonemarks
79
from pythainlp.corpus import thai_orst_words
810
from pythainlp.tokenize import Tokenizer
@@ -17,7 +19,7 @@
1719
_dict_aksonhan[i + i + j + i] = i + "ั" + j + i
1820
_dict_aksonhan[i + i] = "ั" + i
1921
_set_aksonhan = set(_dict_aksonhan.keys())
20-
_trie = Trie(list(_dict_aksonhan.keys()) + list(thai_consonants))
22+
_trie = Trie(chain(_dict_aksonhan.keys(), thai_consonants))
2123
_tokenizer = Tokenizer(custom_dict=_trie, engine="mm")
2224
_dict_thai = set(thai_orst_words()) # call Thai words
2325

pythainlp/benchmarks/word_tokenization.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ def _flatten_result(my_dict: dict, sep: str = ":") -> dict:
5656
:return: a one-dimension dictionary with keys combined
5757
:rtype: dict[str, float | str]
5858
"""
59-
items = []
60-
for k1, kv2 in my_dict.items():
61-
for k2, v in kv2.items():
62-
new_key = f"{k1}{sep}{k2}"
63-
items.append((new_key, v))
64-
65-
return dict(items)
59+
return {
60+
f"{k1}{sep}{k2}": v
61+
for k1, kv2 in my_dict.items()
62+
for k2, v in kv2.items()
63+
}
6664

6765

6866
def benchmark(ref_samples: list[str], samples: list[str]) -> pd.DataFrame:
@@ -259,5 +257,5 @@ def _find_words_correctly_tokenised(
259257
"""
260258
ref_b = dict(zip(ref_boundaries, [1] * len(ref_boundaries)))
261259

262-
labels = tuple(map(lambda x: ref_b.get(x, 0), predicted_boundaries))
260+
labels = tuple(ref_b.get(x, 0) for x in predicted_boundaries)
263261
return labels

pythainlp/cli/benchmark.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
def _read_file(path):
1515
with open(path, encoding="utf-8") as f:
16-
lines = map(lambda r: r.strip(), f.readlines())
16+
lines = (r.strip() for r in f.readlines())
1717
return list(lines)
1818

1919

pythainlp/corpus/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ def find_synonyms(word: str) -> list[str]:
372372
list_synonym.extend(synonyms["synonym"][idx])
373373
list_synonym.append(synonyms["word"][idx])
374374

375-
list_synonym = sorted(list(set(list_synonym)))
375+
list_synonym = sorted(set(list_synonym))
376376

377377
if word in list_synonym: # remove same word
378378
list_synonym.remove(word)

pythainlp/corpus/core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ def get_corpus_default_db(name: str, version: str = "") -> str | None:
188188
with open(default_db_path, encoding="utf-8-sig") as fh:
189189
corpus_db = json.load(fh)
190190

191-
if name in list(corpus_db.keys()):
192-
if version in list(corpus_db[name]["versions"].keys()):
191+
if name in corpus_db:
192+
if version in corpus_db[name]["versions"]:
193193
return path_pythainlp_corpus(
194194
corpus_db[name]["versions"][version]["filename"]
195195
)
@@ -247,7 +247,7 @@ def get_corpus_path(
247247
CUSTOMIZE: dict[str, str] = {
248248
# "the corpus name":"path"
249249
}
250-
if name in list(CUSTOMIZE):
250+
if name in CUSTOMIZE:
251251
return CUSTOMIZE[name]
252252

253253
default_path = get_corpus_default_db(name=name, version=version)

pythainlp/corpus/oscar.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ def word_freqs() -> list[tuple[str, int]]:
2828
path = str(path)
2929

3030
with open(path, encoding="utf-8-sig") as f:
31-
lines = list(f.readlines())
32-
del lines[0]
33-
for line in lines:
31+
next(f) # Skip header line
32+
for line in f:
3433
temp = line.strip().split(",")
3534
if len(temp) >= 2:
3635
if temp[0] != " " and '"' not in temp[0]:
@@ -51,10 +50,9 @@ def unigram_word_freqs() -> dict[str, int]:
5150
path = str(path)
5251

5352
with open(path, encoding="utf-8-sig") as fh:
54-
lines = list(fh.readlines())
55-
del lines[0]
56-
for i in lines:
57-
temp = i.strip().split(",")
53+
next(fh) # Skip header line
54+
for line in fh:
55+
temp = line.strip().split(",")
5856
if temp[0] != " " and '"' not in temp[0]:
5957
freqs[temp[0]] = int(temp[-1])
6058
elif temp[0] == " ":

pythainlp/corpus/tnc.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ def word_freqs() -> list[tuple[str, int]]:
2929
Credit: Korakot Chaovavanich https://www.facebook.com/groups/thainlp/posts/434330506948445
3030
"""
3131
freqs: list[tuple[str, int]] = []
32-
lines = list(get_corpus(_UNIGRAM_FILENAME))
33-
for line in lines:
32+
for line in get_corpus(_UNIGRAM_FILENAME):
3433
word_freq = line.split("\t")
3534
if len(word_freq) >= 2:
3635
freqs.append((word_freq[0], int(word_freq[1])))
@@ -42,9 +41,8 @@ def unigram_word_freqs() -> dict[str, int]:
4241
"""Get unigram word frequency from Thai National Corpus (TNC)
4342
"""
4443
freqs: dict[str, int] = defaultdict(int)
45-
lines = list(get_corpus(_UNIGRAM_FILENAME))
46-
for i in lines:
47-
_temp = i.strip().split(" ")
44+
for line in get_corpus(_UNIGRAM_FILENAME):
45+
_temp = line.strip().split(" ")
4846
if len(_temp) >= 2:
4947
freqs[_temp[0]] = int(_temp[-1])
5048

@@ -60,10 +58,14 @@ def bigram_word_freqs() -> dict[tuple[str, str], int]:
6058
return freqs
6159
path = str(path)
6260

63-
with open(path, encoding="utf-8-sig") as fh:
64-
for i in fh.readlines():
65-
temp = i.strip().split(" ")
66-
freqs[(temp[0], temp[1])] = int(temp[-1])
61+
try:
62+
with open(path, encoding="utf-8-sig") as fh:
63+
for line in fh:
64+
temp = line.strip().split(" ")
65+
if len(temp) >= 3:
66+
freqs[(temp[0], temp[1])] = int(temp[-1])
67+
except (IOError, OSError):
68+
pass
6769

6870
return freqs
6971

@@ -77,9 +79,13 @@ def trigram_word_freqs() -> dict[tuple[str, str, str], int]:
7779
return freqs
7880
path = str(path)
7981

80-
with open(path, encoding="utf-8-sig") as fh:
81-
for i in fh.readlines():
82-
temp = i.strip().split(" ")
83-
freqs[(temp[0], temp[1], temp[2])] = int(temp[-1])
82+
try:
83+
with open(path, encoding="utf-8-sig") as fh:
84+
for line in fh:
85+
temp = line.strip().split(" ")
86+
if len(temp) >= 4:
87+
freqs[(temp[0], temp[1], temp[2])] = int(temp[-1])
88+
except (IOError, OSError):
89+
pass
8490

8591
return freqs

pythainlp/corpus/ttc.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ def word_freqs() -> list[tuple[str, int]]:
2424
<https://github.com/PyThaiNLP/pythainlp/blob/dev/pythainlp/corpus/ttc_freq.txt>`_)
2525
"""
2626
freqs: list[tuple[str, int]] = []
27-
lines = list(get_corpus(_UNIGRAM_FILENAME))
28-
for line in lines:
27+
for line in get_corpus(_UNIGRAM_FILENAME):
2928
word_freq = line.split("\t")
3029
if len(word_freq) >= 2:
3130
freqs.append((word_freq[0], int(word_freq[1])))
@@ -38,9 +37,8 @@ def unigram_word_freqs() -> dict[str, int]:
3837
"""
3938
freqs: dict[str, int] = defaultdict(int)
4039

41-
lines = list(get_corpus(_UNIGRAM_FILENAME))
42-
for i in lines:
43-
temp = i.strip().split(" ")
40+
for line in get_corpus(_UNIGRAM_FILENAME):
41+
temp = line.strip().split(" ")
4442
if len(temp) >= 2:
4543
freqs[temp[0]] = int(temp[-1])
4644

0 commit comments

Comments
 (0)