Python:多处理 - 改进函数时间6x不会影响循环的性能

时间:2016-11-11 13:36:27

标签: python-2.7

人吗? 我有一个功能:

    def _process_sensor(self, last_value, raw_data, raw_string, tariff_data, counter, electricity):
        raw_data = OrderedDict(sorted(raw_data.items(), key=lambda t: iso8601.parse_date(t[0])))
        interval_data = self._transform_cumulative_to_interval(last_value, raw_data, electricity)
        interval_data = self._calculate_sensor_commodities(interval_data, tariff_data, tariff_data['ID'], electricity)
        self._persist_results(raw_string, interval_data, tariff_data['ID'], electricity)

昨天每个函数执行花了2s,今天我把它改进了大概0.25s并且我很高兴但是当我调用我的函数时:

from multiprocessing.pool import ThreadPool as Pool

pool = Pool(processes=8)

for sensor_id in today_values:
    try:
        pool.apply(self._process_sensor, (yesterday_values[sensor_id], today_values[sensor_id],
                                                  raw_string[sensor_id], self.electricity_tariff_data[sensor_id],
                                                  processed, True, ))
    except Exception as e:
        self.logger.warning('Some data error: {}'.format(e))
    processed += 1

循环100个元素需要相同的时间:大约24秒。我能做错什么?传递的参数是字典的一部分。 self._persist_results从s3transfer.manager导入TransferManager调用AWS。

编辑:我知道我有一个8核心的盒子,我正在运行代码。并且使用相同的结果进行了pool.apply_async。

2 个答案:

答案 0 :(得分:0)

如果单次运行需要0.25秒而100运行需要24秒,则听起来该功能正在进行争用,因此其大部分运行时间并不是并行执行的。当I / O资源存在争用时,这是很常见的,所以我的猜测是_persist_results调用是罪魁祸首。

展望TransferManagermax_concurrency似乎有[TransferConfig][1]设置 - 看起来应默认为10,您是否有机会减少这种情况?我建议检查是否已设置,如果没有,请查看是否明确设置有帮助。

答案 1 :(得分:0)

修正了它:

-(void)fetchDateFromString:(NSString*)stringObj
{

    NSError *error = NULL;
    NSDataDetector *detectorObj = [NSDataDetector dataDetectorWithTypes:(NSTextCheckingTypes)NSTextCheckingTypeDate error:&error];

    NSArray *matchesObj = [detectorObj matchesInString:stringObj
                                         options:0
                                           range:NSMakeRange(0, [stringObj length])];

    NSLocale* currentLoc = [NSLocale currentLocale];
    for (NSTextCheckingResult *match in matchesObj) {
        if ([match resultType] == NSTextCheckingTypeDate) {
            NSLog(@"Date : %@", [[match date] descriptionWithLocale:currentLoc]);
        }
    }
}

没有时间检查copy.deepcopy是否有必要(并且说实话我不需要将它放在一个单独的循环中 - 我会尽快重构)。