-
-
Save stephenVertex/4f02350032f7bc2ae64fbf20e71ae8f3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import seaborn as sns | |
import matplotlib.pyplot as plt | |
import pandas as pd | |
## Calculate gp2 price, and return max throughput and IOPS | |
def mkGp2(vol_size_gb): | |
### See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/general-purpose.html#gp2-performance | |
d = {} | |
d['price'] = 0.10 * vol_size_gb | |
if vol_size_gb < 33.33: | |
d['iops'] = 100 | |
else: | |
d['iops'] = min(16000, 3 * vol_size_gb) | |
## Calculate throughput max, ignoring bursting from 170 to 334. | |
if vol_size_gb <= 334: | |
d['throughput_max'] = 128 | |
else: | |
d['throughput_max'] = 250 | |
return(d) | |
## Calculate gp3 price, as a function of size, required IOPS | |
## and required throughput | |
def mkGp3(vol_size_gb, req_iops, req_throughput): | |
storage_price = 0.08 * vol_size_gb | |
prov_iops = min(13000, max(req_iops - 3000, 0)) | |
prov_iops_price = 0.005 * prov_iops | |
prov_throughput = min(875, max(req_throughput - 125, 0)) | |
prov_throughput_price = 0.040 * prov_throughput | |
d = {} | |
d['price'] = storage_price + prov_iops_price + prov_throughput_price | |
d['iops'] = 3000 + prov_iops | |
d['throughput_max'] = 125 + prov_throughput | |
d['price_details'] = { | |
'storage' : storage_price, | |
'prov_iops': prov_iops_price, | |
'prov_throughput' : prov_throughput_price | |
} | |
return(d) | |
def transform_df(df): | |
""" | |
Given an input data frame, transport it to have a volume_type column. | |
This makes it easier to plot. | |
""" | |
melted_df = df.melt(id_vars=['size_gb'], value_vars=['price_gp2', 'price_gp3'], var_name='volume_type', value_name='price') | |
melted_df['volume_type'] = melted_df['volume_type'].apply(lambda x: x.split('_')[-1]) | |
return melted_df | |
def plot_df(df): | |
""" | |
Create a simple line plot of the price vs volume type | |
""" | |
sns.lineplot(x="size_gb", y="price", data=df, hue="volume_type") | |
plt.show() | |
def plot_df_2y(df_price, df_ratio): | |
""" | |
Create a two axis line plot where the left axis has the price comparison and the right | |
axis has the ratio | |
""" | |
fig, ax1 = plt.subplots() | |
sns.lineplot(x="size_gb", y="price", data=df_price, hue="volume_type", ax=ax1) | |
ax2 = ax1.twinx() | |
sns.lineplot(x="size_gb", y="ratio", data=df_ratio, color="yellow", ax=ax2) | |
plt.show() | |
## Iterate over sizes from 1GB to 16TB, in 100GB steps | |
sizes = range(1, 16000, 10) | |
prices = [] | |
for size_gb in sizes: | |
gp2 = lib2.mkGp2(size_gb) | |
gp3 = lib2.mkGp3(size_gb, gp2['iops'], gp2['throughput_max']) | |
x = { 'size_gb' : size_gb, | |
'price_gp2' : gp2['price'], | |
'price_gp3' : gp3['price'] | |
} | |
prices.append(x) | |
## Transform and plot data | |
df1 = pd.DataFrame(prices) | |
df2 = transform_df(df1) | |
price_ratio = df1.assign(ratio=df1["price_gp3"]/df1["price_gp2"])[['size_gb', 'ratio']] | |
price_ratio = price_ratio[price_ratio['size_gb'] > 1] | |
plot_df_2y(df2, price_ratio) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
lib2 seems a mistake