首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConfigParser慢吗?ConfigParser与丑陋的算法

ConfigParser慢吗?ConfigParser与丑陋的算法
EN

Stack Overflow用户
提问于 2020-11-27 14:57:51
回答 1查看 316关注 0票数 0

我试图改进我创建的函数,以便将一堆INI文件解析为单个JSON文件。当我编写这个函数时,我还是个新手,我不知道configparser模块,所以现在我想利用它。

输入:INI文件(父文件),包含对其他INI文件(子文件)的一长组引用。

目标:将INI父文件转换为JSON,并包含从获取的一些信息--所有的--子文件。换句话说:从一组INI文件中获取一些信息,并将它们导出到一个JSON文件中。

问题:我希望我的新代码至少和旧代码一样快,但事实并非如此:它比旧代码慢了2倍。为什么会这样呢?是ConfigParser还是我?性能非常重要,我的函数解析大约900个INI文件需要1秒,而旧的则需要半秒钟。

父例

(它可以从数百行到数万):

代码语言:javascript
复制
[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行):

代码语言:javascript
复制
[General]
Name = name
ID = 12345
...

[Options]
...

JSON输出示例

代码语言:javascript
复制
{
    "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": "..." 
        }
    }
}

旧码

代码语言:javascript
复制
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

新码

代码语言:javascript
复制
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 
EN

回答 1

Stack Overflow用户

发布于 2020-11-27 15:16:18

我期望我的新代码至少和旧代码一样快,但事实并非如此:它比旧代码慢了2倍。为什么会这样呢?是ConfigParser还是我?

两者都是。要了解在代码和ConfigParser中花费时间的位置,您应该考虑使用Profilerhttps://docs.python.org/3/library/profile.html是学习如何分析代码的一个很好的起点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65039436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档