{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Copyright 2021 Amazon.com and its affiliates; all rights reserved. This file is AWS Content and may not be duplicated or distributed without permission" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Demonstrating aspects of Amazon SageMaker Feature Store performance" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from utilities.feature_store_helper import FeatureStore\n", "import boto3\n", "import sagemaker\n", "import json\n", "from datetime import timedelta\n", "from datetime import datetime\n", "import time\n", "import pytz\n", "utc=pytz.UTC\n", "\n", "smfs_runtime = boto3.session.Session().client(service_name='sagemaker-featurestore-runtime')\n", "default_bucket = sagemaker.Session().default_bucket()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "FG_NAME = 'fs-demo-2022-03-24'\n", "\n", "fs = FeatureStore()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Performance demo 1: Online store, feature lookups" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import time\n", "import numpy as np\n", "\n", "def print_percentiles(latencies):\n", " latency_dict = np.array([int(np.percentile(latencies, 50)), \n", " int(np.percentile(latencies, 90)), \n", " int(np.percentile(latencies, 95))])#,\n", "\n", " print('p50 p90 p95') #p99 p99.5 p99.7 p99.8 p99.9')\n", " print(latency_dict)\n", " return\n", "\n", "def get_record(fg_name, max_id):\n", " start_time = time.time()\n", " fs._featurestore_runtime.get_record(FeatureGroupName=fg_name,\n", " RecordIdentifierValueAsString=str(np.random.randint(0, max_id)))\n", " end_time = time.time()\n", " elapsed_time = (end_time - start_time)*1000\n", " return int(elapsed_time)\n", "\n", "def test_gets(fg_name, max_id=100000, num_iterations=1000):\n", " latencies = []\n", " sample = num_iterations // 10\n", " for request_num in range(num_iterations):\n", " elapsed_time = get_record(fg_name, max_id)\n", " latencies.append(elapsed_time)\n", " return latencies" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'ResponseMetadata': {'RequestId': '6b60577d-ffb1-4114-b304-87b66c26018b',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'x-amzn-requestid': '6b60577d-ffb1-4114-b304-87b66c26018b',\n", " 'content-type': 'application/json',\n", " 'content-length': '215',\n", " 'date': 'Tue, 13 Sep 2022 23:12:08 GMT'},\n", " 'RetryAttempts': 0},\n", " 'Record': [{'FeatureName': 'Id', 'ValueAsString': '6'},\n", " {'FeatureName': 'UpdateTime', 'ValueAsString': '2020-02-03T00:00:00Z'},\n", " {'FeatureName': 'ZipCode', 'ValueAsString': '33333'},\n", " {'FeatureName': 'Churn', 'ValueAsString': '0'}]}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fs._featurestore_runtime.get_record(FeatureGroupName=FG_NAME,\n", " RecordIdentifierValueAsString='6')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "p50 p90 p95\n", "[7 8 9]\n" ] } ], "source": [ "latencies = test_gets(FG_NAME, max_id=6, num_iterations=5000)\n", "print_percentiles(latencies)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Performance demo 2: Feature ingestion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Sample input file with 200+ features" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "ename": "ParserError", "evalue": "Error tokenizing data. C error: Expected 204 fields in line 13032, saw 286\n", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mParserError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpandas\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mdf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'utilities/data-001.csv'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'{df.shape[0]:,d} rows'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/util/_decorators.py\u001b[0m in \u001b[0;36mwrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 309\u001b[0m \u001b[0mstacklevel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstacklevel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 310\u001b[0m )\n\u001b[0;32m--> 311\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 312\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 313\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/io/parsers/readers.py\u001b[0m in \u001b[0;36mread_csv\u001b[0;34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, error_bad_lines, warn_bad_lines, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options)\u001b[0m\n\u001b[1;32m 584\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkwds_defaults\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 585\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 586\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_read\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 587\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 588\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/io/parsers/readers.py\u001b[0m in \u001b[0;36m_read\u001b[0;34m(filepath_or_buffer, kwds)\u001b[0m\n\u001b[1;32m 486\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 487\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 488\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnrows\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 489\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 490\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/io/parsers/readers.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, nrows)\u001b[0m\n\u001b[1;32m 1045\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnrows\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1046\u001b[0m \u001b[0mnrows\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalidate_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"nrows\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnrows\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1047\u001b[0;31m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcol_dict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnrows\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1048\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1049\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/io/parsers/c_parser_wrapper.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, nrows)\u001b[0m\n\u001b[1;32m 222\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 223\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlow_memory\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 224\u001b[0;31m \u001b[0mchunks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reader\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_low_memory\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnrows\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 225\u001b[0m \u001b[0;31m# destructive to chunks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 226\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_concatenate_chunks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchunks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.TextReader.read_low_memory\u001b[0;34m()\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.TextReader._read_rows\u001b[0;34m()\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.TextReader._tokenize_rows\u001b[0;34m()\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/pandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.raise_parser_error\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mParserError\u001b[0m: Error tokenizing data. C error: Expected 204 fields in line 13032, saw 286\n" ] } ], "source": [ "import pandas as pd\n", "df = pd.read_csv('utilities/data-001.csv')\n", "print(f'{df.shape[0]:,d} rows')\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ingest a single file directly from the notebook" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "FG_NAME = 'fs-demo-2022-03-24'" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'df' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: name 'df' is not defined" ] } ], "source": [ "%%time\n", "fs.ingest_from_df(FG_NAME, df, max_processes=12, max_workers=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Now experiment with different feature pipeline configurations" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def run_once(instance_type, instance_count, input_uri, fg_name=FG_NAME, script='utilities/customer_v2.py'):\n", " if instance_type == 'ml.m5.4xlarge':\n", " max_processes = 16\n", " elif instance_type == 'ml.c5.9xlarge':\n", " max_processes = 36\n", " elif instance_type == 'ml.c5.18xlarge':\n", " max_processes = 72\n", " \n", " before_launch = datetime.now()\n", "\n", " print(f'Launching pipeline with {instance_count} {instance_type} instances ')\n", " print(f' to feature group: {fg_name}')\n", " print(f' using data from : {input_uri}...')\n", " \n", " #fs.disable_feature_pipeline(fg_name)\n", " sm = boto3.client('sagemaker')\n", " time.sleep(5)\n", " fs.update_feature_pipeline(input_uri, fg_name, script, \n", " instance_type=instance_type, instance_count=instance_count,\n", " max_processes=max_processes, max_workers=4)\n", " fs.enable_feature_pipeline(fg_name)\n", "\n", " new_executions = True\n", " iterations = 0\n", " while new_executions:\n", " if iterations == 0:\n", " print(' Waiting for pipeline to start executing...')\n", " iterations += 1\n", " \n", " summs = sm.list_pipeline_executions(PipelineName=f'sm-pipeline-{fg_name}')['PipelineExecutionSummaries']\n", " if len(summs) > 0:\n", " if summs[0]['StartTime'] > utc.localize(before_launch):\n", " break\n", " time.sleep(5)\n", " \n", " print(' Pipeline is now executing.')\n", " done = False\n", " mins = 0\n", " while not done:\n", " summs = sm.list_pipeline_executions(PipelineName=f'sm-pipeline-{fg_name}')['PipelineExecutionSummaries']\n", " if mins == 0:\n", " print(' Waiting for pipeline to complete executing...')\n", " mins += 1\n", " if summs[0]['StartTime'] > utc.localize(before_launch):\n", " status = summs[0]['PipelineExecutionStatus']\n", " if not status == 'Executing':\n", " print(f' Final status: {status}')\n", " break\n", " time.sleep(30)\n", " \n", " print(' Pipeline completed.\\n')\n", " return" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Use an S3 location with 20 input files, 2 million feature records by 204 features" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#s3_base_uri = f's3://{default_bucket}/sagemaker-feature-store/customer-bulk-test/'\n", "s3_base_uri = f's3://{default_bucket}/sagemaker-feature-store/hello-data/'\n", "\n", "s3_base_uri" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ingest using m5.4xl, increasing the number of instances to reduce job runtime" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Launching pipeline with 1 ml.m5.4xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n", "Launching pipeline with 2 ml.m5.4xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n", "Launching pipeline with 4 ml.m5.4xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n", "Launching pipeline with 8 ml.m5.4xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n" ] } ], "source": [ "run_once('ml.m5.4xlarge', 1, s3_base_uri)\n", "run_once('ml.m5.4xlarge', 2, s3_base_uri)\n", "run_once('ml.m5.4xlarge', 4, s3_base_uri)\n", "run_once('ml.m5.4xlarge', 8, s3_base_uri)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Now ingest using c5.9xl, achieving same speed with fewer instances" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Launching pipeline with 2 ml.c5.9xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n", "Launching pipeline with 3 ml.c5.9xlarge instances \n", " to feature group: fs-demo-2022-03-24\n", " using data from : s3://sagemaker-us-east-1-869044399089/sagemaker-feature-store/hello-data/...\n", " Waiting for pipeline to start executing...\n", " Pipeline is now executing.\n", " Waiting for pipeline to complete executing...\n", " Final status: Failed\n", " Pipeline completed.\n", "\n" ] } ], "source": [ "run_once('ml.c5.9xlarge', 2, s3_base_uri)\n", "run_once('ml.c5.9xlarge', 3, s3_base_uri)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Sample ingestion run times and throughput\n", "![Ingestion performance](ingest.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "latencies = test_gets('customers', num_customers, 3000)\n", "print_percentiles(latencies)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "latencies = test_gets('customers', 3000)\n", "print_percentiles(latencies)" ] } ], "metadata": { "instance_type": "ml.m5.large", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 4 }