我在AWS Lambda中有两个功能,如下所示。第一个汇总每小时的数据并返回平均值。第二个执行矩阵乘法。
当我在本地运行这些函数时,执行矩阵乘法的函数要慢50倍,因为它必须比计算小时平均值的函数执行更多的运算。但是,当我在AWS Lambda上运行它们时,执行矩阵乘法的函数会更快,有时甚至快两倍。怎么可能呢?
这是进口商计算每小时平均值:
import json
import time
def get_averages(event, context):
"""
file is a JSON object containing sensor data for a whole day.
Retrieves
data from input, transforms it and stores it in another JSON
object.
Input file:
json = [{
"sensor_id": row[0],
"sensor_type": row[1],
"lat": row[3], lon: row[4],
"timestamp": row[5],
"P1": row[6], "durP1": row[7], "ratioP1": row[8],
"P2": row[9], "durP2": row[10], "ratioP2": row[11]
}]
Output object (data aggregated by hour):
data = {
"sensor_id": 1,
"sensor_type": "ABC",
"location": [lat, lon]
"date": "yyyy-mm-dd",
"total_data-points": int,
"data": [
{
"time": "hh:mm:ss",
"data-points": int,
"P1": [1, 2, 3], # ([avg_val, avg_dur, avg_ratio])
"P2": [1, 2, 3], # ([avg_val, avg_dur, avg_ratio])
},
]
}
"""
start = time.perf_counter()
first_row = True
for row in json.loads(event['json_input'].replace('\'', '"')):
# row[5][11:-6] to remove day and '+00'
if (first_row):
out = {
'sensor_id': row['sensor_id'],
'sensor_type': row['sensor_type'],
'location': [row['lat'], row['lon']],
'date': row['timestamp'][:10],
"total_data-points": 0,
'data': [{'hour': row['timestamp'][11:13]}]
}
p1 = ([0, 0, 0], 0) # second element of the tuple counts
p2 = ([0, 0, 0], 0) # data points per hour
first_row = False
elif (row['timestamp'][11:13] != out['data'][-1]['hour']):
# calculate averages
avg_p1 = [x / p1[1] for x in p1[0]]
avg_p2 = [y / p1[1] for y in p2[0]]
# append averages and number of data points
out['total_data-points'] += p1[1]
out['data'][-1]['data-points'] = p1[1]
out['data'][-1]['P1'] = avg_p1
out['data'][-1]['P2'] = avg_p2
# add object for new hour, reset p1, p2
out['data'].append({'hour': row['timestamp'][11:13]})
p1 = ([0, 0, 0], 0)
p2 = ([0, 0, 0], 0)
# add values to p1, p2, increment counters
data_1 = [float(x) for x in [row['P1'], row['durP1'],
row['ratioP1']]]
data_2 = [float(y) for y in [row['P2'], row['durP2'],
row['ratioP2']]]
p1 = ([sum(x) for x in zip(p1[0], data_1)], p1[1] + 1)
p2 = ([sum(x) for x in zip(p1[0], data_2)], p2[1] + 1)
# add last elements to the json object when EOF is reached
avg_p1 = [x / p1[1] for x in p1[0]]
avg_p2 = [y / p1[1] for y in p2[0]]
out['total_data-points'] += p1[1]
out['data'][-1]['data-points'] = p1[1]
out['data'][-1]['P1'] = avg_p1
out['data'][-1]['P2'] = avg_p2
perf = time.perf_counter() - start
return {
'statusCode': 200,
'body': json.dumps({"output": out, "time": perf})
}
这是执行矩阵乘法的函数:
import json
import time
def get_matrix(event, context):
"""
file is a JSON object containing sensor data for a whole day.
Retrieves
data from input, transforms it and stores it in another JSON
object.
Input file:
json = [{
"sensor_id": row[0],
"sensor_type": row[1],
"lat": row[3], lon: row[4],
"timestamp": row[5],
"P1": row[6], "durP1": row[7], "ratioP1": row[8],
"P2": row[9], "durP2": row[10], "ratioP2": row[11]
}]
Output object:
data = {
"sensor_id": 1,
"sensor_type": "ABC",
"location": [lat, lon]
"date": "yyyy-mm-dd",
"data": [
{
"start_time": "hh:mm:ss",
"end_time": "hh:mm:ss",
"result": 2D-array
},
]
}
"""
start = time.perf_counter()
first_row = True
cnt_rows = 0
cnt_cols = 0
matrix = [[]]
for row in json.loads(event['json_input'].replace('\'', '"')):
# row[5][11:-6] to remove day and '+00'
if (first_row):
out = {
'sensor_id': row['sensor_id'],
'sensor_type': row['sensor_type'],
'location': [row['lat'], row['lon']],
'date': row['timestamp'][:10],
'data': [{}]
}
first_row = False
if cnt_rows == 1:
out['data'][-1]['start_time']: row['timestamp'][11:13]
if (cnt_cols == event["matrix_size"]):
cnt_cols = 0
cnt_rows += 1
if (cnt_rows == event["matrix_size"]):
out['data'][-1]['end_time'] = row['timestamp'][11:13]
out['data'][-1]['result'] = matrix_square(matrix)
out['data'].append({})
matrix = [[]]
cnt_rows = 0
else:
matrix.append([])
matrix[-1].extend([float(row['P1']), float(row['durP1']),
float(row['ratioP1']), float(row['P2']),
float(row['durP2']), float(row['ratioP2'])])
cnt_cols += 6
perf = time.perf_counter() - start
return {
'statusCode': 200,
'body': json.dumps({"output": out, "time": perf})
}
def matrix_square(matrix):
res = []
for i in range(len(matrix)):
res.append([])
for j in range(len(matrix)):
row = matrix[i]
col = [r[j] for r in matrix]
res[-1].append(0)
for k in range(len(row)):
res[i][j] += row[k] * col[k]
return res
答案 0 :(得分:0)
在lambda中,每当您尝试运行function时。 AWS会在第一时间根据您的功能需求自动为您的功能分配资源,这就是这样做的原因。 而且此资源会保留一段时间,因此有时您第二次运行功能将花费更少的时间,而之前花费的时间更少。