diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 67447d58ae635692fbae553c4118fb7d7cdaecf6..72cb1ab852b1df1ca868548c1da2b26cd14f34a4 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -87,6 +87,10 @@ var (
 		Name:  "verbosity",
 		Usage: "sets the verbosity level",
 	}
+	BenchFlag = cli.BoolFlag{
+		Name:  "bench",
+		Usage: "benchmark the execution",
+	}
 	CreateFlag = cli.BoolFlag{
 		Name:  "create",
 		Usage: "indicates the action should be create rather than call",
@@ -124,6 +128,7 @@ var (
 
 func init() {
 	app.Flags = []cli.Flag{
+		BenchFlag,
 		CreateFlag,
 		DebugFlag,
 		VerbosityFlag,
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index cecbf360639aac958edfe9b663bcc6d7cecaef7d..da301ff5ee5ee7f04ed7e51bfdd32ed6ac91afd6 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -25,6 +25,7 @@ import (
 	"os"
 	goruntime "runtime"
 	"runtime/pprof"
+	"testing"
 	"time"
 
 	"github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
@@ -69,6 +70,33 @@ func readGenesis(genesisPath string) *core.Genesis {
 	return genesis
 }
 
+func timedExec(bench bool, execFunc func() ([]byte, uint64, error)) ([]byte, uint64, time.Duration, error) {
+	var (
+		output   []byte
+		gasLeft  uint64
+		execTime time.Duration
+		err      error
+	)
+
+	if bench {
+		result := testing.Benchmark(func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				output, gasLeft, err = execFunc()
+			}
+		})
+
+		// Get the average execution time from the benchmarking result.
+		// There are other useful stats here that could be reported.
+		execTime = time.Duration(result.NsPerOp())
+	} else {
+		startTime := time.Now()
+		output, gasLeft, err = execFunc()
+		execTime = time.Since(startTime)
+	}
+
+	return output, gasLeft, execTime, err
+}
+
 func runCmd(ctx *cli.Context) error {
 	glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
 	glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name)))
@@ -116,11 +144,7 @@ func runCmd(ctx *cli.Context) error {
 		receiver = common.HexToAddress(ctx.GlobalString(ReceiverFlag.Name))
 	}
 
-	var (
-		code []byte
-		ret  []byte
-		err  error
-	)
+	var code []byte
 	codeFileFlag := ctx.GlobalString(CodeFileFlag.Name)
 	codeFlag := ctx.GlobalString(CodeFlag.Name)
 
@@ -203,10 +227,10 @@ func runCmd(ctx *cli.Context) error {
 	} else {
 		runtimeConfig.ChainConfig = params.AllEthashProtocolChanges
 	}
-	tstart := time.Now()
-	var leftOverGas uint64
+
 	var hexInput []byte
 	if inputFileFlag := ctx.GlobalString(InputFileFlag.Name); inputFileFlag != "" {
+		var err error
 		if hexInput, err = ioutil.ReadFile(inputFileFlag); err != nil {
 			fmt.Printf("could not load input from file: %v\n", err)
 			os.Exit(1)
@@ -215,16 +239,24 @@ func runCmd(ctx *cli.Context) error {
 		hexInput = []byte(ctx.GlobalString(InputFlag.Name))
 	}
 	input := common.FromHex(string(bytes.TrimSpace(hexInput)))
+
+	var execFunc func() ([]byte, uint64, error)
 	if ctx.GlobalBool(CreateFlag.Name) {
 		input = append(code, input...)
-		ret, _, leftOverGas, err = runtime.Create(input, &runtimeConfig)
+		execFunc = func() ([]byte, uint64, error) {
+			output, _, gasLeft, err := runtime.Create(input, &runtimeConfig)
+			return output, gasLeft, err
+		}
 	} else {
 		if len(code) > 0 {
 			statedb.SetCode(receiver, code)
 		}
-		ret, leftOverGas, err = runtime.Call(receiver, input, &runtimeConfig)
+		execFunc = func() ([]byte, uint64, error) {
+			return runtime.Call(receiver, input, &runtimeConfig)
+		}
 	}
-	execTime := time.Since(tstart)
+
+	output, leftOverGas, execTime, err := timedExec(ctx.GlobalBool(BenchFlag.Name), execFunc)
 
 	if ctx.GlobalBool(DumpFlag.Name) {
 		statedb.Commit(true)
@@ -267,7 +299,7 @@ Gas used:           %d
 `, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas)
 	}
 	if tracer == nil {
-		fmt.Printf("0x%x\n", ret)
+		fmt.Printf("0x%x\n", output)
 		if err != nil {
 			fmt.Printf(" error: %v\n", err)
 		}