[英]Is ConfigParser slow? ConfigParser vs. an ugly algorithm
我試圖改進我創建的 function 以將一堆 INI 文件解析為單個 JSON 文件。 當我寫這個 function 時我是一個新手,我不知道configparser
模塊,所以現在我想利用它。
INPUT :INI 文件(父)包含對其他 INI 文件(子)的一長串引用。
目標:將 INI 父文件轉換為 JSON 並包含從所有子文件中獲取的一些信息。 換句話說:從一組 INI 文件中獲取一些信息並將它們導出到單個 JSON 文件中。
問題:我希望我的新代碼至少和舊代碼一樣快,但事實並非如此:它慢了 2 倍。 這是為什么? 是 ConfigParser 還是我? 性能真的很重要,我的 function 需要一秒鍾來解析大約 900 個 INI 文件,而舊的需要半秒鍾。
(它可以有數百行到數萬行):
[General]
Name = parent
...
[Item 000001]
Name = first item
path = "path/to/child_1.ini"
...
[Item 000002]
Name = second item
...
[...]
[Item 001000]
Name = thousandth item
...
(它可以有少於 100 行到大約 200 行):
[General]
Name = name
ID = 12345
...
[Options]
...
{
"Parent": {
"Name": "parent",
"Count": "1000",
[...]
"child1": {
"Name": "name",
"ID": "12345",
"Option1": "...",
"Option2": "...",
"Option3": "..."
},
"child2": {
"Name": "name2",
"ID": "22222",
"Option1": "...",
"Option2": "...",
"Option3": "..."
},
[...]
"child1000": {
"Name": "name1000",
"ID": "12332",
"Option1": "...",
"Option2": "...",
"Option3": "..."
}
}
}
def split_string_by_equal(string):
str_operands = string.split(' = ')
first_part = (str_operands[0]).strip()
second_part = (' '.join(str_operands[1:])).strip()
return [first_part, second_part]
def parse_ini_to_json(path):
parent_dict = {}
child_dict = {}
num_child = 1
parent_directory = os.path.dirname(testflow)
with open(path, 'r') as parent_file:
for line in tfl_file:
left_part = split_string_by_equal(line)[0]
right_part = split_string_by_equal(line)[1]
if left_part in SOME_WORDS:
parent_dict.update({left_part: do_something(parent_directory, right_part)})
elif left_part == 'Count':
parent_dict.update({'Count': right_part})
elif left_part == 'JohnDoe':
parent_dict['JohnDoe'] = right_part
elif 'Item' in line:
if child_dict:
parent_dict.update({'test{}'.format(num_child): child_dict})
child_dict = {}
num_child += 1
elif left_part in SOME_OTHER_WORDS:
child_dict.update({left_part: right_part})
if left_part == 'path':
child_dict.update(extract_data_from_child(right_part))
if child_dict:
parent_dict.update({'child{}'.format(num_test): child_dict})
return parent_dict
def extract_data_from_child(path):
""" same methodology used in above function """
[...]
return child_dict
def get_config_parser(path):
config = configparser.ConfigParser()
config.optionxform = str
config.read(path)
return config
def parse_ini_to_json(path):
config = get_config_parser(path)
parent_directory = os.path.dirname(testflow)
parent_dict = {}
for key in config['Folders'].keys():
parent_dict[key] = do_something( parent_directory, config['Folders'][key])
parent_dict['Count'] = config['General']['Count']
parent_dict['JohnDoe'] = config['General']['JohnDoe']
counter = 1
for key in config.keys():
if 'Item' in key:
child_dict = {}
for child_prop in config[key].keys():
if child_prop in SOME_WORDS:
child_dict[child_prop] = config[key][child_prop]
child_path = config[key]['path']
child_dict.update(extract_data_from_child(child_path))
child_dict[f'child{counter}'] = child_dict
counter += 1
return parent_dict
def extract_data_from_child(path):
config = sysfunc.get_config_parser(path)
child_dict = {}
for key in config['General'].keys():
if key in SOME_KEYWORDS:
child_dict[key] = config['General'][key]
for key in config['Levels'].keys():
if key in SOME_OTHER_KEYWORDS:
child_dict[key] = config['Options'][key]
try:
some_value = config['Levels']['SomeKey']
except KeyError:
pass
for key in config['Options'].keys():
value = config['Options'][key]
key_enabled = key.strip() + 'enabled'
try:
if config['Options'][key_enabled] == '0':
continue
except KeyError:
continue
if 'false' in value:
value = '0'
elif 'true' in value:
value = '1'
child_dict[key] = value
return child_dict
我希望我的新代碼至少和舊代碼一樣快,但事實並非如此:它慢了 2 倍。 這是為什么? 是 ConfigParser 還是我?
兩者都是。 要了解在您的代碼和 ConfigParser 中花費的時間,您應該考慮使用Profiler 。 https://docs.python.org/3/library/profile.html是學習如何分析代碼的一個很好的起點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.