Python 配置解析器慢吗?ConfigParser与丑陋的算法
我试图改进我创建的一个函数,将一组INI文件解析为一个JSON文件。当我编写这个函数时,我是一个新手,不知道Python 配置解析器慢吗?ConfigParser与丑陋的算法,python,performance,ini,configparser,Python,Performance,Ini,Configparser,我试图改进我创建的一个函数,将一组INI文件解析为一个JSON文件。当我编写这个函数时,我是一个新手,不知道configparser模块,所以现在我想利用它 输入:包含对其他INI文件(子项)的一长组引用的INI文件(父项) 目标:将INI父文件转换为JSON,并将从所有子文件获取的部分信息包含在其中。换句话说:从一组INI文件中获取一些信息,并将它们导出到单个JSON文件中 问题:我希望我的新代码至少和旧代码一样快,但事实并非如此:它慢了两倍。为什么呢?是我还是我?性能非常重要,我的函数需要一
configparser
模块,所以现在我想利用它
输入:包含对其他INI文件(子项)的一长组引用的INI文件(父项)
目标:将INI父文件转换为JSON,并将从所有子文件获取的部分信息包含在其中。换句话说:从一组INI文件中获取一些信息,并将它们导出到单个JSON文件中
问题:我希望我的新代码至少和旧代码一样快,但事实并非如此:它慢了两倍。为什么呢?是我还是我?性能非常重要,我的函数需要一秒钟来解析大约900个INI文件,而旧函数需要半秒钟
父示例
(它可以有数百行到上万行):
儿童榜样
(它可以有少于100行到大约200行):
JSON输出示例
旧代码
新代码
我希望我的新代码至少和旧代码一样快,但事实并非如此:它慢了2倍。为什么呢?是我还是我
两者都有。要了解代码和ConfigParser中花费的时间,您应该看看如何使用探查器。是学习如何分析代码的良好起点
[General]
Name = parent
...
[Item 000001]
Name = first item
path = "path/to/child_1.ini"
...
[Item 000002]
Name = second item
...
[...]
[Item 001000]
Name = thousandth item
...
[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