diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 6c5b75482dec752a6b434aff9dafc2bc3f3a8618..209208c58fa939e6b1319fdcc67a97efcbee5272 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
 	spec_version: 216,
-	impl_version: 0,
+	impl_version: 1,
 	apis: RUNTIME_API_VERSIONS,
 };
 
@@ -813,6 +813,7 @@ impl_runtime_apis! {
 		{
 			match module.as_slice() {
 				b"pallet-identity" | b"identity" => Identity::run_benchmark(extrinsic, steps, repeat).ok(),
+				b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark(extrinsic, steps, repeat).ok(),
 				_ => return None,
 			}
 		}
diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs
index 0a4a143ea9dd10edb364f445d01574fe7a4355ab..86ec6b30c9de3cbc4826f0d8cb10103422967e5a 100644
--- a/substrate/frame/identity/src/benchmarking.rs
+++ b/substrate/frame/identity/src/benchmarking.rs
@@ -20,7 +20,7 @@ use super::*;
 
 use frame_system::RawOrigin;
 use sp_io::hashing::blake2_256;
-use sp_runtime::{BenchmarkResults, BenchmarkParameter};
+use sp_runtime::{BenchmarkResults, BenchmarkParameter, selected_benchmark};
 use sp_runtime::traits::{Bounded, Benchmarking, BenchmarkingSetup, Dispatchable};
 
 use crate::Module as Identity;
@@ -514,7 +514,7 @@ impl<T: Trait> BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>> for
 }
 
 // The list of available benchmarks for this pallet.
-enum SelectedBenchmark {
+selected_benchmark!(
 	AddRegistrar,
 	SetIdentity,
 	SetSubs,
@@ -525,46 +525,8 @@ enum SelectedBenchmark {
 	SetAccountId,
 	SetFields,
 	ProvideJudgement,
-	KillIdentity,
-}
-
-// Allow us to select a benchmark from the list of available benchmarks.
-
-impl<T: Trait> BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>> for SelectedBenchmark {
-	fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> {
-		match self {
-			Self::AddRegistrar => <AddRegistrar as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&AddRegistrar),
-			Self::SetIdentity => <SetIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&SetIdentity),
-			Self::SetSubs => <SetSubs as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&SetSubs),
-			Self::ClearIdentity => <ClearIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&ClearIdentity),
-			Self::RequestJudgement => <RequestJudgement as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&RequestJudgement),
-			Self::CancelRequest => <CancelRequest as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&CancelRequest),
-			Self::SetFee => <SetFee as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&SetFee),
-			Self::SetAccountId => <SetAccountId as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&SetAccountId),
-			Self::SetFields => <SetFields as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&SetFields),
-			Self::ProvideJudgement => <ProvideJudgement as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&ProvideJudgement),
-			Self::KillIdentity => <KillIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&KillIdentity),
-		}
-	}
-
-	fn instance(&self, components: &[(BenchmarkParameter, u32)])
-		-> Result<(crate::Call<T>, RawOrigin<T::AccountId>), &'static str>
-	{
-		match self {
-			Self::AddRegistrar => <AddRegistrar as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&AddRegistrar, components),
-			Self::SetIdentity => <SetIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&SetIdentity, components),
-			Self::SetSubs => <SetSubs as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&SetSubs, components),
-			Self::ClearIdentity => <ClearIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&ClearIdentity, components),
-			Self::RequestJudgement => <RequestJudgement as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&RequestJudgement, components),
-			Self::CancelRequest => <CancelRequest as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&CancelRequest, components),
-			Self::SetFee => <SetFee as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&SetFee, components),
-			Self::SetAccountId => <SetAccountId as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&SetAccountId, components),
-			Self::SetFields => <SetFields as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&SetFields, components),
-			Self::ProvideJudgement => <ProvideJudgement as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&ProvideJudgement, components),
-			Self::KillIdentity => <KillIdentity as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::instance(&KillIdentity, components),
-		}
-	}
-}
+	KillIdentity
+);
 
 impl<T: Trait> Benchmarking<BenchmarkResults> for Module<T> {
 	fn run_benchmark(extrinsic: Vec<u8>, steps: u32, repeat: u32) -> Result<Vec<BenchmarkResults>, &'static str> {
diff --git a/substrate/frame/timestamp/Cargo.toml b/substrate/frame/timestamp/Cargo.toml
index f2d6f405828c700aa845b738f2dd01994d1435c6..e68392f9e9a9f9824e38ee26a317559d347981f7 100644
--- a/substrate/frame/timestamp/Cargo.toml
+++ b/substrate/frame/timestamp/Cargo.toml
@@ -9,6 +9,7 @@ license = "GPL-3.0"
 serde = { version = "1.0.101", optional = true }
 codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
 sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" }
+sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" }
 sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
 sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" }
 frame-support = { version = "2.0.0", default-features = false, path = "../support" }
diff --git a/substrate/frame/timestamp/src/benchmarking.rs b/substrate/frame/timestamp/src/benchmarking.rs
new file mode 100644
index 0000000000000000000000000000000000000000..55d6d7e0467409d513dccce4169a45347245a351
--- /dev/null
+++ b/substrate/frame/timestamp/src/benchmarking.rs
@@ -0,0 +1,105 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Timestamp pallet benchmarking.
+
+use super::*;
+
+use sp_std::prelude::*;
+
+use frame_system::RawOrigin;
+use sp_runtime::{BenchmarkResults, BenchmarkParameter, selected_benchmark};
+use sp_runtime::traits::{Benchmarking, BenchmarkingSetup, Dispatchable};
+
+/// Benchmark `set` extrinsic.
+struct Set;
+impl<T: Trait> BenchmarkingSetup<T, Call<T>, RawOrigin<T::AccountId>> for Set {
+	fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> {
+		vec![
+			// Current time ("Now")
+			(BenchmarkParameter::N, 1, 100),
+		]
+	}
+
+	fn instance(&self, components: &[(BenchmarkParameter, u32)])
+		-> Result<(Call<T>, RawOrigin<T::AccountId>), &'static str>
+	{
+		let user_origin = RawOrigin::None;
+		let now = components.iter().find(|&c| c.0 == BenchmarkParameter::N).unwrap().1;
+
+		// Return the `set` call
+		Ok((Call::<T>::set(now.into()), user_origin))
+	}
+}
+
+selected_benchmark!(Set);
+
+impl<T: Trait> Benchmarking<BenchmarkResults> for Module<T> {
+	fn run_benchmark(extrinsic: Vec<u8>, steps: u32, repeat: u32) -> Result<Vec<BenchmarkResults>, &'static str> {
+		// Map the input to the selected benchmark.
+		let selected_benchmark = match extrinsic.as_slice() {
+			b"set" => SelectedBenchmark::Set,
+			_ => return Err("Could not find extrinsic."),
+		};
+		
+		// Warm up the DB
+		sp_io::benchmarking::commit_db();
+		sp_io::benchmarking::wipe_db();
+
+		let components = <SelectedBenchmark as BenchmarkingSetup<T, crate::Call<T>, RawOrigin<T::AccountId>>>::components(&selected_benchmark);
+		let mut results: Vec<BenchmarkResults> = Vec::new();
+
+		// Select the component we will be benchmarking. Each component will be benchmarked.
+		for (name, low, high) in components.iter() {
+			// Create up to `STEPS` steps for that component between high and low.
+			let step_size = ((high - low) / steps).max(1);
+			let num_of_steps = (high - low) / step_size;
+			for s in 0..num_of_steps {
+				// This is the value we will be testing for component `name`
+				let component_value = low + step_size * s;
+
+				// Select the mid value for all the other components.
+				let c: Vec<(BenchmarkParameter, u32)> = components.iter()
+					.map(|(n, l, h)|
+						(*n, if n == name { component_value } else { (h - l) / 2 + l })
+					).collect();
+
+				// Run the benchmark `repeat` times.
+				for _ in 0..repeat {
+					// Set up the externalities environment for the setup we want to benchmark.
+					let (call, caller) = <SelectedBenchmark as BenchmarkingSetup<
+						T,
+						Call<T>,
+						RawOrigin<T::AccountId>,
+					>>::instance(&selected_benchmark, &c)?;
+					// Commit the externalities to the database, flushing the DB cache.
+					// This will enable worst case scenario for reading from the database.
+					sp_io::benchmarking::commit_db();
+					// Run the benchmark.
+					let start = sp_io::benchmarking::current_time();
+					call.dispatch(caller.into())?;
+					let finish = sp_io::benchmarking::current_time();
+					let elapsed = finish - start;
+					results.push((c.clone(), elapsed));
+					// Wipe the DB back to the genesis state.
+					sp_io::benchmarking::wipe_db();
+				}
+			}
+		}
+
+		return Ok(results);
+	}
+}
diff --git a/substrate/frame/timestamp/src/lib.rs b/substrate/frame/timestamp/src/lib.rs
index 1c16ed6380a92a702151a38982a6313d79fb82b0..c437c325cdab35defb68a4e3cdff1523221c62dd 100644
--- a/substrate/frame/timestamp/src/lib.rs
+++ b/substrate/frame/timestamp/src/lib.rs
@@ -90,6 +90,8 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
+mod benchmarking;
+
 use sp_std::{result, cmp};
 use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier};
 use frame_support::{Parameter, decl_storage, decl_module};
diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits.rs
index 645725e1bf4e9b08673a50a846bef2a27a1c8dc4..c28fe555f7b3f658328e3074ec05f3fb0a94031d 100644
--- a/substrate/primitives/runtime/src/traits.rs
+++ b/substrate/primitives/runtime/src/traits.rs
@@ -1333,6 +1333,55 @@ pub trait BenchmarkingSetup<T, Call, RawOrigin> {
 	fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(Call, RawOrigin), &'static str>;
 }
 
+/// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`.
+///
+/// Every variant must implement [`BenchmarkingSetup`](crate::traits::BenchmarkingSetup).
+///
+/// ```nocompile
+///
+/// struct Transfer;
+/// impl BenchmarkingSetup for Transfer { ... }
+///
+/// struct SetBalance;
+/// impl BenchmarkingSetup for SetBalance { ... }
+///
+/// selected_benchmark!(Transfer, SetBalance);
+/// ```
+#[macro_export]
+macro_rules! selected_benchmark {
+	($($bench:ident),*) => {
+		// The list of available benchmarks for this pallet.
+		enum SelectedBenchmark {
+			$( $bench, )*
+		}
+
+		// Allow us to select a benchmark from the list of available benchmarks.
+		impl<T: Trait> $crate::traits::BenchmarkingSetup<T, Call<T>, RawOrigin<T::AccountId>> for SelectedBenchmark {
+			fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> {
+				match self {
+					$( Self::$bench => <$bench as $crate::traits::BenchmarkingSetup<
+						T,
+						Call<T>,
+						RawOrigin<T::AccountId>,
+					>>::components(&$bench), )*
+				}
+			}
+
+			fn instance(&self, components: &[(BenchmarkParameter, u32)])
+				-> Result<(Call<T>, RawOrigin<T::AccountId>), &'static str>
+			{
+				match self {
+					$( Self::$bench => <$bench as $crate::traits::BenchmarkingSetup<
+						T,
+						Call<T>,
+						RawOrigin<T::AccountId>,
+					>>::instance(&$bench, components), )*
+				}
+			}
+		}
+	};
+}
+
 #[cfg(test)]
 mod tests {
 	use super::*;