You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by st...@apache.org on 2021/10/18 14:10:11 UTC

[impala] 01/02: IMPALA-10950: Update expr-benchmark.cc

This is an automated email from the ASF dual-hosted git repository.

stigahuang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 1e92c097d97dd4c688b8994e3ea63e8de80e35ec
Author: Riza Suminto <ri...@cloudera.com>
AuthorDate: Fri Oct 1 14:21:53 2021 -0700

    IMPALA-10950: Update expr-benchmark.cc
    
    With the introduction of PlanRootSink by IMPALA-2905, query planner has
    moved the scalar expression's thrift definition from
    'fragments[0].output_sink.output_exprs' to
    'fragments[0].plan.nodes[0].union_node.const_expr_lists[0]' for a
    constant query. This patch adjusts expr-benchmark.cc to generate the
    ScalarExpr from the right thrift location and also modify the helper
    class to ensure proper resource cleanup at the end of the benchmark. We
    explicitly set ENABLE_EXPR_REWRITES=0 to prevent expression rewrite by
    FoldConstantsRule.java.
    
    The benchmark used to run without codegen. This patch modifies the
    benchmark to run a benchmark suite both with and without codegen.
    
    Testing:
    - Run and verify that expr-benchmark does not crash.
    
    Change-Id: I5b17434d85e32a58622bffb64a697b062a8bf43f
    Reviewed-on: http://gerrit.cloudera.org:8080/17894
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/benchmarks/expr-benchmark.cc | 945 ++++++++++++++++++++++++------------
 1 file changed, 632 insertions(+), 313 deletions(-)

diff --git a/be/src/benchmarks/expr-benchmark.cc b/be/src/benchmarks/expr-benchmark.cc
index f915096..0ece02f 100644
--- a/be/src/benchmarks/expr-benchmark.cc
+++ b/be/src/benchmarks/expr-benchmark.cc
@@ -18,156 +18,209 @@
 #include <stdio.h>
 #include <iostream>
 
-#include <jni.h>
-#include <thrift/Thrift.h>
-#include <thrift/protocol/TDebugProtocol.h>
-
 #include "runtime/exec-env.h"
 #include "runtime/runtime-state.h"
 
-#include "exprs/scalar-expr.h"
 #include "exprs/scalar-expr-evaluator.h"
-#include "util/backend-gflag-util.h"
+#include "exprs/scalar-expr.h"
+#include "exprs/timezone_db.h"
 #include "util/benchmark.h"
-#include "util/cpu-info.h"
-#include "util/debug-util.h"
-#include "util/jni-util.h"
-#include "rpc/jni-thrift-util.h"
 
-#include "gen-cpp/Types_types.h"
-#include "gen-cpp/ImpalaService.h"
-#include "gen-cpp/DataSinks_types.h"
-#include "gen-cpp/Types_types.h"
-#include "gen-cpp/ImpalaService.h"
-#include "gen-cpp/ImpalaService_types.h"
-#include "gen-cpp/Frontend_types.h"
-#include "gen-cpp/ImpalaService.h"
-#include "gen-cpp/Frontend_types.h"
-#include "rpc/thrift-server.h"
 #include "codegen/llvm-codegen.h"
 #include "common/init.h"
 #include "common/object-pool.h"
 #include "common/status.h"
+#include "common/thread-debug-info.h"
+#include "gen-cpp/DataSinks_types.h"
+#include "gen-cpp/Frontend_types.h"
+#include "gen-cpp/Types_types.h"
 #include "runtime/fragment-state.h"
 #include "runtime/mem-pool.h"
 #include "runtime/mem-tracker.h"
-#include "runtime/query-state.h"
 #include "service/fe-support.h"
 #include "service/frontend.h"
 #include "service/impala-server.h"
 
 #include "common/names.h"
 
+DECLARE_string(hdfs_zone_info_zip);
+
 using namespace apache::thrift;
 using namespace impala;
 
+// Struct holding reference to RuntimeState, FragmentState, ScalarExpr, and
+// ScalarExprEvaluator for a specific expression.
+// This ExprTestData should be obtained through Planner::PrepareScalarExpression() that
+// will populate all the objects and open the ScalarExprEvaluator.
+struct ExprTestData {
+  ExprTestData(RuntimeState* state, FragmentState* fragment_state, ScalarExpr* expr,
+      ScalarExprEvaluator* eval)
+    : state_(state),
+      fragment_state_(fragment_state),
+      expr_(expr),
+      eval_(eval),
+      dummy_result_(0) {}
+
+  ~ExprTestData() {
+    eval_->Close(state_);
+    expr_->Close();
+    fragment_state_->ReleaseResources();
+    state_->ReleaseResources();
+  }
+
+  RuntimeState* state_;
+  FragmentState* fragment_state_;
+  ScalarExpr* expr_;
+  ScalarExprEvaluator* eval_;
+  int64_t dummy_result_;
+};
+
 // Utility class to take (ascii) sql and return the plan.  This does minimal
 // error handling.
 class Planner {
  public:
-  Planner() {
+  Planner() : mem_pool_(&tracker_) {
     frontend_.SetCatalogIsReady();
     ABORT_IF_ERROR(exec_env_.InitForFeSupport());
+    query_options_.enable_expr_rewrites = false;
   }
 
-  ~Planner() {
-    if (fragment_state_ != nullptr) fragment_state_->ReleaseResources();
-  }
+  // Tell planner to enable/disable codegen on PrepareScalarExpression.
+  void EnableCodegen(bool enable) { query_options_.__set_disable_codegen(!enable); }
 
-  Status GeneratePlan(const string& stmt, TExecRequest* result) {
+  // Create ExprTestData for a given query.
+  // Returned *test_data contains valid ExprTestData* in which eval_ is already opened.
+  // Assumes 'query' is a constant query.
+  Status PrepareScalarExpression(const string& query, ExprTestData** test_data) {
+    TExecRequest request;
     TQueryCtx query_ctx;
-    query_ctx.client_request.stmt = stmt;
-    query_ctx.client_request.query_options = query_options_;
     query_ctx.__set_session(session_state_);
+    query_ctx.client_request.__set_stmt(query);
+    query_ctx.client_request.__set_query_options(query_options_);
     string dummy_hostname = "";
     TNetworkAddress dummy_addr;
     ImpalaServer::PrepareQueryContext(dummy_hostname, dummy_addr, &query_ctx);
-    runtime_state_.reset(new RuntimeState(query_ctx, &exec_env_));
-    TPlanFragment* fragment = runtime_state_->obj_pool()->Add(new TPlanFragment());
-    PlanFragmentCtxPB* fragment_ctx =
-        runtime_state_->obj_pool()->Add(new PlanFragmentCtxPB());
-    fragment_state_ = runtime_state_->obj_pool()->Add(
-        new FragmentState(runtime_state_->query_state(), *fragment, *fragment_ctx));
-
-    return frontend_.GetExecRequest(query_ctx, result);
-  }
 
-  RuntimeState* GetRuntimeState() { return runtime_state_.get(); }
+    RuntimeState* state = pool_.Add(new RuntimeState(query_ctx, &exec_env_));
+    TPlanFragment* fragment = state->obj_pool()->Add(new TPlanFragment());
+    PlanFragmentCtxPB* fragment_ctx = state->obj_pool()->Add(new PlanFragmentCtxPB());
+
+    FragmentState* fragment_state = state->obj_pool()->Add(
+        new FragmentState(state->query_state(), *fragment, *fragment_ctx));
+    RETURN_IF_ERROR(frontend_.GetExecRequest(query_ctx, &request));
+
+    // For query "select 1 + 1", planner will return query plan:
+    //
+    // F00:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
+    // |  Per-Host Resources: mem-estimate=4.00MB mem-reservation=4.00MB thread-reservation=1
+    // PLAN-ROOT SINK
+    // |  output exprs: 1 + 1
+    // |  mem-estimate=4.00MB mem-reservation=4.00MB spill-buffer=2.00MB thread-reservation=0
+    // |
+    // 00:UNION
+    //    constant-operands=1
+    //    mem-estimate=0B mem-reservation=0B thread-reservation=0
+    //    tuple-ids=0 row-size=2B cardinality=1
+    //
+    // However, the TExpr for the scalar expression is not in the output_sink's
+    // output_exprs. Instead, it is in the union node's const_expr_lists.
+    const TQueryExecRequest& query_request = request.query_exec_request;
+    TUnionNode union_node =
+        query_request.plan_exec_info[0].fragments[0].plan.nodes[0].union_node;
+    vector<TExpr> texprs = union_node.const_expr_lists[0];
+    DCHECK_EQ(texprs.size(), 1);
+
+    ScalarExpr* expr;
+    RETURN_IF_ERROR(
+        ScalarExpr::Create(texprs[0], RowDescriptor(), fragment_state, &expr));
+    ScalarExprEvaluator* eval;
+    RETURN_IF_ERROR(
+        ScalarExprEvaluator::Create(*expr, state, &pool_, &mem_pool_, &mem_pool_, &eval));
+
+    // UDFs which cannot be interpreted need to be handled by codegen.
+    // This follow examples from fe-support.cc
+    if (fragment_state->ScalarExprNeedsCodegen()) {
+      RETURN_IF_ERROR(fragment_state->CreateCodegen());
+      LlvmCodeGen* codegen = fragment_state->codegen();
+      DCHECK(codegen != NULL);
+      RETURN_IF_ERROR(fragment_state->CodegenScalarExprs());
+      codegen->EnableOptimizations(true);
+      RETURN_IF_ERROR(codegen->FinalizeModule());
+    }
+    RETURN_IF_ERROR(eval->Open(state));
 
-  FragmentState* GetFragmentState() { return fragment_state_; }
+    *test_data = pool_.Add(new ExprTestData(state, fragment_state, expr, eval));
+    return Status::OK();
+  }
 
  private:
   Frontend frontend_;
   ExecEnv exec_env_;
-  scoped_ptr<RuntimeState> runtime_state_;
-  FragmentState* fragment_state_;
 
   TQueryOptions query_options_;
   TSessionState session_state_;
-};
 
-struct TestData {
-  ScalarExprEvaluator* eval;
-  int64_t dummy_result;
+  ObjectPool pool_;
+  MemTracker tracker_;
+  MemPool mem_pool_;
 };
 
 Planner* planner;
-ObjectPool pool;
-MemTracker tracker;
-MemPool mem_pool(&tracker);
-
-// Utility function to get prepare select list for exprs.  Assumes this is a
-// constant query.
-static Status PrepareSelectList(
-    const TExecRequest& request, ScalarExprEvaluator** eval) {
-  const TQueryExecRequest& query_request = request.query_exec_request;
-  vector<TExpr> texprs = query_request.plan_exec_info[0].fragments[0].output_sink.output_exprs;
-  DCHECK_EQ(texprs.size(), 1);
-  RuntimeState* state = planner->GetRuntimeState();
-  ScalarExpr* expr;
-  RETURN_IF_ERROR(
-      ScalarExpr::Create(texprs[0], RowDescriptor(), planner->GetFragmentState(), &expr));
-  RETURN_IF_ERROR(
-      ScalarExprEvaluator::Create(*expr, state, &pool, &mem_pool, &mem_pool, eval));
-  return Status::OK();
+
+static string BenchmarkName(const string& name, bool codegen) {
+  if (!codegen) {
+    return name;
+  } else {
+    return name + "Codegen";
+  }
 }
 
-// TODO: handle codegen.  Codegen needs a new driver that is also codegen'd.
-static TestData* GenerateBenchmarkExprs(const string& query, bool codegen) {
+static ExprTestData* GenerateBenchmarkExprs(const string& query) {
   stringstream ss;
   ss << "select " << query;
-  TestData* test_data = new TestData;
-  TExecRequest request;
-  ABORT_IF_ERROR(planner->GeneratePlan(ss.str(), &request));
-  ABORT_IF_ERROR(PrepareSelectList(request, &test_data->eval));
-  return test_data;
+  ExprTestData* test_data = nullptr;
+  ABORT_IF_ERROR(planner->PrepareScalarExpression(ss.str(), &test_data));
+  if (test_data == nullptr) {
+    ABORT_WITH_ERROR("Failed to prepare ExprTestData for query '" + ss.str() + "'");
+  } else {
+    return test_data;
+  }
 }
 
 const int ITERATIONS = 256;
 
 // Benchmark driver to run expr multiple times.
 void BenchmarkQueryFn(int batch_size, void* d) {
-  TestData* data = reinterpret_cast<TestData*>(d);
+  ExprTestData* data = reinterpret_cast<ExprTestData*>(d);
   for (int i = 0; i < batch_size; ++i) {
     for (int n = 0; n < ITERATIONS; ++n) {
-      void* value = data->eval->GetValue(NULL);
+      void* value = data->eval_->GetValue(NULL);
       // Dummy result to prevent this from being optimized away
-      data->dummy_result += reinterpret_cast<int64_t>(value);
+      data->dummy_result_ += reinterpret_cast<int64_t>(value);
     }
   }
 }
 
-#define BENCHMARK(name, stmt)\
-  suite->AddBenchmark(name, BenchmarkQueryFn, GenerateBenchmarkExprs(stmt, false))
-// Machine Info: Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
-// Literals:             Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                            int                2154                  1X
-//                          float                2155              1.001X
-//                         double                2179              1.011X
-//                         string                2179              1.011X
-Benchmark* BenchmarkLiterals() {
-  Benchmark* suite = new Benchmark("Literals");
+#define BENCHMARK(name, stmt) \
+  suite->AddBenchmark(name, BenchmarkQueryFn, GenerateBenchmarkExprs(stmt))
+// Machine Info: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
+// Literals:                  Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                                 int                700      706      710         1X         1X         1X
+//                               float                397      400      402     0.567X     0.566X     0.567X
+//                              double                396      401      403     0.566X     0.568X     0.568X
+//                              string                668      674      676     0.954X     0.954X     0.952X
+//
+// LiteralsCodegen:           Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                                 int                780      786      790         1X         1X         1X
+//                               float                610      615      617     0.783X     0.783X     0.781X
+//                              double                610      616      619     0.782X     0.784X     0.783X
+//                              string                780      786      790         1X         1X         1X
+Benchmark* BenchmarkLiterals(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("Literals", codegen));
   BENCHMARK("int", "1");
   BENCHMARK("float", "1.1f");
   BENCHMARK("double", "1.1");
@@ -175,29 +228,47 @@ Benchmark* BenchmarkLiterals() {
   return suite;
 }
 
-// Arithmetic:           Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                        int-add               527.5                  1X
-//                     double-add                 528              1.001X
-Benchmark* BenchmarkArithmetic() {
-  Benchmark* suite = new Benchmark("Arithmetic");
+// Arithmetic:                Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                             int-add                319      323      324         1X         1X         1X
+//                          double-add                 40     40.3     40.5     0.125X     0.125X     0.125X
+//
+// ArithmeticCodegen:         Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                             int-add                781      787      791         1X         1X         1X
+//                          double-add                610      617      619     0.781X     0.784X     0.783X
+Benchmark* BenchmarkArithmetic(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("Arithmetic", codegen));
   BENCHMARK("int-add", "1 + 2");
   BENCHMARK("double-add", "1.1 + 2.2");
   return suite;
 }
 
-// Machine Info: Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
-// Like:                 Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                         equals               203.9                  1X
-//                     not equals               426.4              2.091X
-//                         strstr               142.8             0.7001X
-//                       strncmp1               269.7              1.323X
-//                       strncmp2               294.1              1.442X
-//                       strncmp3               775.7              3.804X
-//                          regex                19.7             0.0966X
-Benchmark* BenchmarkLike() {
-  Benchmark* suite = new Benchmark("Like");
+// Like:                      Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                              equals                254      255      257         1X         1X         1X
+//                          not equals                320      322      324      1.26X      1.26X      1.26X
+//                              strstr                106      107      107     0.419X     0.419X     0.418X
+//                            strncmp1                215      216      217     0.848X     0.847X     0.845X
+//                            strncmp2                209      211      211     0.825X     0.825X     0.822X
+//                            strncmp3                254      256      257         1X         1X         1X
+//                               regex               28.1     28.2     28.3     0.111X      0.11X      0.11X
+//
+// LikeCodegen:               Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                              equals                820      827      830         1X         1X         1X
+//                          not equals                824      829      836         1X         1X      1.01X
+//                              strstr                130      131      131     0.158X     0.158X     0.158X
+//                            strncmp1                334      337      339     0.407X     0.408X     0.408X
+//                            strncmp2                355      359      360     0.433X     0.434X     0.434X
+//                            strncmp3                468      472      474     0.571X     0.571X     0.572X
+//                               regex               29.3     29.5     29.6    0.0357X    0.0357X    0.0357X
+Benchmark* BenchmarkLike(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("Like", codegen));
   BENCHMARK("equals", "'abcdefghijklmnopqrstuvwxyz' = 'abcdefghijklmnopqrstuvwxyz'");
   BENCHMARK("not equals", "'abcdefghijklmnopqrstuvwxyz' = 'lmnopqrstuvwxyz'");
   BENCHMARK("strstr", "'abcdefghijklmnopqrstuvwxyz' LIKE '%lmnopq%'");
@@ -208,20 +279,35 @@ Benchmark* BenchmarkLike() {
   return suite;
 }
 
-// Cast:                 Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                     int_to_int                 824                  1X
-//                    int_to_bool                 878              1.066X
-//                  int_to_double               775.4              0.941X
-//                  int_to_string               32.47            0.03941X
-//              double_to_boolean               823.5             0.9994X
-//               double_to_bigint               775.4              0.941X
-//               double_to_string               4.682           0.005682X
-//                  string_to_int               402.6             0.4886X
-//                string_to_float               145.8             0.1769X
-//            string_to_timestamp               83.76             0.1017X
-Benchmark* BenchmarkCast() {
-  Benchmark* suite = new Benchmark("Cast");
+// Cast:                      Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                          int_to_int                334      337      340         1X         1X         1X
+//                         int_to_bool                332      335      338     0.995X     0.994X     0.992X
+//                       int_to_double                700      707      711       2.1X       2.1X      2.09X
+//                       int_to_string                125      126      127     0.374X     0.375X     0.374X
+//                   double_to_boolean                155      156      157     0.464X     0.463X     0.463X
+//                    double_to_bigint                 90     90.6     90.8     0.269X     0.269X     0.267X
+//                    double_to_string                 68     68.8     69.3     0.204X     0.204X     0.204X
+//                       string_to_int                229      231      232     0.684X     0.685X     0.682X
+//                     string_to_float                103      104      105     0.309X     0.308X     0.308X
+//                 string_to_timestamp               39.9     40.1     40.5     0.119X     0.119X     0.119X
+//
+// CastCodegen:               Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                          int_to_int                824      830      837         1X         1X         1X
+//                         int_to_bool                815      821      828     0.989X     0.989X     0.989X
+//                       int_to_double                778      783      789     0.944X     0.943X     0.943X
+//                       int_to_string                167      169      171     0.203X     0.203X     0.204X
+//                   double_to_boolean                819      826      833     0.994X     0.994X     0.995X
+//                    double_to_bigint                777      783      792     0.943X     0.943X     0.946X
+//                    double_to_string                139      140      141     0.168X     0.168X     0.168X
+//                       string_to_int                369      372      375     0.448X     0.448X     0.448X
+//                     string_to_float                123      124      125      0.15X      0.15X      0.15X
+//                 string_to_timestamp               44.8     45.1     45.4    0.0544X    0.0543X    0.0542X
+Benchmark* BenchmarkCast(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("Cast", codegen));
   BENCHMARK("int_to_int", "cast(1 as INT)");
   BENCHMARK("int_to_bool", "cast(1 as BOOLEAN)");
   BENCHMARK("int_to_double", "cast(1 as DOUBLE)");
@@ -235,72 +321,178 @@ Benchmark* BenchmarkCast() {
   return suite;
 }
 
-Benchmark* BenchmarkDecimalCast() {
-  Benchmark* suite = new Benchmark("Decimal Casts");
-  BENCHMARK("int_to_decimal4", "cast 12345678 as DECIMAL(9,2)");
-  BENCHMARK("decimal4_to_decimal4", "cast 12345678.5 as DECIMAL(9,2)");
-  BENCHMARK("decimal8_to_decimal4", "cast 12345678.345 as DECIMAL(9,2)");
-  BENCHMARK("decimal16_to_decimal4", "cast 12345678.123456783456789 as DECIMAL(9,2)");
-  BENCHMARK("double_to_decimal4", "cast e() as DECIMAL(9,7)");
-  BENCHMARK("string_to_decimal4", "cast '12345678.123456783456789' as DECIMAL(9,2)");
-  BENCHMARK("int_to_decimal8", "cast 12345678 as DECIMAL(18,2)");
-  BENCHMARK("decimal4_to_decimal8", "cast 12345678.5 as DECIMAL(18,2)");
-  BENCHMARK("decimal8_to_decimal8", "cast 12345678.345 as DECIMAL(18,2)");
-  BENCHMARK("decimal16_to_decimal8", "cast 12345678.123456783456789 as DECIMAL(18,2)");
-  BENCHMARK("double_to_decimal8", "cast e() as DECIMAL(18,7)");
-  BENCHMARK("string_to_decimal8", "cast '12345678.123456783456789' as DECIMAL(18,7)");
-  BENCHMARK("int_to_decimal16", "cast 12345678 as DECIMAL(28,2)");
-  BENCHMARK("decimal4_to_decimal16", "cast 12345678.5 as DECIMAL(28,2)");
-  BENCHMARK("decimal8_to_decimal16", "cast 12345678.345 as DECIMAL(28,2)");
-  BENCHMARK("decimal16_to_decimal16", "cast 12345678.123456783456789 as DECIMAL(28,2)");
-  BENCHMARK("double_to_decimal16", "cast e() as DECIMAL(28,7)");
-  BENCHMARK("string_to_decimal16", "cast '12345678.123456783456789' as DECIMAL(28,7)");
-  BENCHMARK("decimal4_to_tinyint", "cast 78.5 as TINYINT");
-  BENCHMARK("decimal8_to_tinyint", "cast 0.12345678345 as TINYINT");
-  BENCHMARK("decimal16_to_tinyint", "cast 78.12345678123456783456789 as TINYINT");
-  BENCHMARK("decimal4_to_smallint", "cast 78.5 as SMALLINT");
-  BENCHMARK("decimal8_to_smallint", "cast 0.12345678345 as SMALLINT");
-  BENCHMARK("decimal16_to_smallint", "cast 78.12345678123456783456789 as SMALLINT");
-  BENCHMARK("decimal4_to_int", "cast 12345678.5 as INT");
-  BENCHMARK("decimal8_to_int", "cast 12345678.345 as INT");
-  BENCHMARK("decimal16_to_int", "cast 12345678.123456783456789 as INT");
-  BENCHMARK("decimal4_to_bigint", "cast 12345678.5 as BIGINT");
-  BENCHMARK("decimal8_to_bigint", "cast 12345678.345 as BIGINT");
-  BENCHMARK("decimal16_to_bigint", "cast 12345678.123456783456789 as BIGINT");
-  BENCHMARK("decimal4_to_float", "cast 12345678.5 as FLOAT");
-  BENCHMARK("decimal8_to_float", "cast 12345678.345 as FLOAT");
-  BENCHMARK("decimal16_to_float", "cast 12345678.123456783456789 as FLOAT");
-  BENCHMARK("decimal4_to_double", "cast 12345678.5 as DOUBLE");
-  BENCHMARK("decimal8_to_double", "cast 12345678.345 as DOUBLE");
-  BENCHMARK("decimal16_to_double", "cast 12345678.123456783456789 as DOUBLE");
-  BENCHMARK("decimal4_to_string", "cast 12345678.5 as STRING");
-  BENCHMARK("decimal8_to_string", "cast 12345678.345 as STRING");
-  BENCHMARK("decimal16_to_string", "cast 12345678.123456783456789 as STRING");
+// DecimalCasts:              Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                     int_to_decimal4                104      105      105         1X         1X         1X
+//                decimal4_to_decimal4                396      399      402       3.8X       3.8X      3.82X
+//                decimal8_to_decimal4                 44       44     44.4     0.422X      0.42X     0.421X
+//               decimal16_to_decimal4               31.3     31.6     31.7       0.3X     0.301X     0.301X
+//                  double_to_decimal4               58.4     58.9     59.5      0.56X     0.562X     0.565X
+//                  string_to_decimal4               50.9     51.1     51.4     0.488X     0.488X     0.488X
+//                     int_to_decimal8                114      115      116      1.09X       1.1X       1.1X
+//                decimal4_to_decimal8               51.3     51.6     52.1     0.492X     0.492X     0.494X
+//                decimal8_to_decimal8                 44     44.4     44.6     0.422X     0.423X     0.423X
+//               decimal16_to_decimal8               31.6     31.9       32     0.303X     0.304X     0.303X
+//                  double_to_decimal8               60.6     60.8     61.1     0.582X     0.581X      0.58X
+//                  string_to_decimal8               43.1     43.6       44     0.414X     0.416X     0.417X
+//                    int_to_decimal16                110      112      113      1.06X      1.07X      1.07X
+//               decimal4_to_decimal16               36.9       37     37.3     0.353X     0.353X     0.353X
+//               decimal8_to_decimal16               43.1     43.5     43.8     0.414X     0.415X     0.415X
+//              decimal16_to_decimal16               31.7     31.8     31.9     0.304X     0.303X     0.303X
+//                 double_to_decimal16               54.2     54.5     54.7      0.52X      0.52X     0.519X
+//                 string_to_decimal16               27.2     27.2     27.4     0.261X      0.26X      0.26X
+//                 decimal4_to_tinyint               89.6     90.3       91      0.86X     0.862X     0.864X
+//                 decimal8_to_tinyint               75.9     76.1     76.3     0.728X     0.726X     0.724X
+//                decimal16_to_tinyint               50.1     50.1     50.5      0.48X     0.478X     0.479X
+//                decimal4_to_smallint               85.6     85.9     86.4     0.821X      0.82X     0.819X
+//                decimal8_to_smallint               77.2     77.6     77.8      0.74X      0.74X     0.738X
+//               decimal16_to_smallint               50.5     50.6     50.9     0.484X     0.483X     0.482X
+//                     decimal4_to_int               86.3     86.6     87.7     0.828X     0.826X     0.832X
+//                     decimal8_to_int               76.9     77.1     77.5     0.738X     0.736X     0.735X
+//                    decimal16_to_int               56.2     56.4     56.6     0.539X     0.538X     0.537X
+//                  decimal4_to_bigint               89.6     89.8     90.4      0.86X     0.857X     0.857X
+//                  decimal8_to_bigint               74.7     74.9     75.3     0.717X     0.715X     0.714X
+//                 decimal16_to_bigint               57.2     57.2     57.5     0.549X     0.546X     0.546X
+//                   decimal4_to_float                700      705      712      6.71X      6.73X      6.75X
+//                   decimal8_to_float                700      704      711      6.72X      6.72X      6.74X
+//                  decimal16_to_float                703      704      711      6.74X      6.72X      6.74X
+//                  decimal4_to_double                700      709      712      6.72X      6.76X      6.75X
+//                  decimal8_to_double                701      708      715      6.72X      6.76X      6.78X
+//                 decimal16_to_double                702      705      712      6.73X      6.73X      6.75X
+//                  decimal4_to_string               54.5       55     55.4     0.523X     0.525X     0.525X
+//                  decimal8_to_string               53.3       54     54.4     0.512X     0.515X     0.516X
+//                 decimal16_to_string               5.81     5.87     5.87    0.0557X     0.056X    0.0556X
+//
+// DecimalCastsCodegen:       Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                     int_to_decimal4                610      614      618         1X         1X         1X
+//                decimal4_to_decimal4                608      615      618     0.996X         1X         1X
+//                decimal8_to_decimal4                610      616      619         1X         1X         1X
+//               decimal16_to_decimal4                610      613      617         1X     0.999X     0.998X
+//                  double_to_decimal4                608      613      617     0.997X     0.998X     0.998X
+//                  string_to_decimal4               83.2     83.5     84.1     0.136X     0.136X     0.136X
+//                     int_to_decimal8                638      645      647      1.05X      1.05X      1.05X
+//                decimal4_to_decimal8                638      642      648      1.05X      1.05X      1.05X
+//                decimal8_to_decimal8                636      645      647      1.04X      1.05X      1.05X
+//               decimal16_to_decimal8                639      642      645      1.05X      1.04X      1.04X
+//                  double_to_decimal8                637      642      647      1.04X      1.05X      1.05X
+//                  string_to_decimal8               79.9     82.5       83     0.131X     0.134X     0.134X
+//                    int_to_decimal16                427      430      434       0.7X       0.7X     0.702X
+//               decimal4_to_decimal16                426      431      433     0.698X     0.702X     0.701X
+//               decimal8_to_decimal16                428      430      434     0.702X     0.701X     0.702X
+//              decimal16_to_decimal16                426      431      435     0.698X     0.702X     0.703X
+//                 double_to_decimal16                427      431      434       0.7X     0.702X     0.702X
+//                 string_to_decimal16               36.7     36.9     37.1    0.0601X      0.06X      0.06X
+//                 decimal4_to_tinyint                777      782      790      1.27X      1.27X      1.28X
+//                 decimal8_to_tinyint                777      785      791      1.27X      1.28X      1.28X
+//                decimal16_to_tinyint                778      784      788      1.28X      1.28X      1.27X
+//                decimal4_to_smallint                776      781      790      1.27X      1.27X      1.28X
+//                decimal8_to_smallint                778      787      790      1.28X      1.28X      1.28X
+//               decimal16_to_smallint                777      783      791      1.27X      1.28X      1.28X
+//                     decimal4_to_int                824      832      836      1.35X      1.35X      1.35X
+//                     decimal8_to_int                823      831      837      1.35X      1.35X      1.35X
+//                    decimal16_to_int                819      825      832      1.34X      1.34X      1.35X
+//                  decimal4_to_bigint                777      783      790      1.27X      1.28X      1.28X
+//                  decimal8_to_bigint                778      786      789      1.28X      1.28X      1.28X
+//                 decimal16_to_bigint                780      783      791      1.28X      1.28X      1.28X
+//                   decimal4_to_float                778      784      790      1.28X      1.28X      1.28X
+//                   decimal8_to_float                778      782      791      1.28X      1.27X      1.28X
+//                  decimal16_to_float                778      785      790      1.28X      1.28X      1.28X
+//                  decimal4_to_double                777      784      789      1.27X      1.28X      1.28X
+//                  decimal8_to_double                777      784      791      1.27X      1.28X      1.28X
+//                 decimal16_to_double                778      784      790      1.28X      1.28X      1.28X
+//                  decimal4_to_string                121      122      124     0.199X     0.199X       0.2X
+//                  decimal8_to_string                121      122      123     0.198X     0.198X     0.199X
+//                 decimal16_to_string               8.42     8.49     8.49    0.0138X    0.0138X    0.0137X
+Benchmark* BenchmarkDecimalCast(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("DecimalCasts", codegen));
+  BENCHMARK("int_to_decimal4", "cast(12345678 as DECIMAL(9,1))");
+  BENCHMARK("decimal4_to_decimal4", "cast(12345678.5 as DECIMAL(9,1))");
+  BENCHMARK("decimal8_to_decimal4", "cast(12345678.345 as DECIMAL(9,1))");
+  BENCHMARK("decimal16_to_decimal4", "cast(12345678.123456783456789 as DECIMAL(9,1))");
+  BENCHMARK("double_to_decimal4", "cast(e() as DECIMAL(9,7))");
+  BENCHMARK("string_to_decimal4", "cast('12345678.123456783456789' as DECIMAL(9,1))");
+  BENCHMARK("int_to_decimal8", "cast(12345678 as DECIMAL(18,2))");
+  BENCHMARK("decimal4_to_decimal8", "cast(12345678.5 as DECIMAL(18,2))");
+  BENCHMARK("decimal8_to_decimal8", "cast(12345678.345 as DECIMAL(18,2))");
+  BENCHMARK("decimal16_to_decimal8", "cast(12345678.123456783456789 as DECIMAL(18,2))");
+  BENCHMARK("double_to_decimal8", "cast(e() as DECIMAL(18,7))");
+  BENCHMARK("string_to_decimal8", "cast('12345678.123456783456789' as DECIMAL(18,7))");
+  BENCHMARK("int_to_decimal16", "cast(12345678 as DECIMAL(28,2))");
+  BENCHMARK("decimal4_to_decimal16", "cast(12345678.5 as DECIMAL(28,2))");
+  BENCHMARK("decimal8_to_decimal16", "cast(12345678.345 as DECIMAL(28,2))");
+  BENCHMARK("decimal16_to_decimal16", "cast(12345678.123456783456789 as DECIMAL(28,2))");
+  BENCHMARK("double_to_decimal16", "cast(e() as DECIMAL(28,7))");
+  BENCHMARK("string_to_decimal16", "cast('12345678.123456783456789' as DECIMAL(28,7))");
+  BENCHMARK("decimal4_to_tinyint", "cast(78.5 as TINYINT)");
+  BENCHMARK("decimal8_to_tinyint", "cast(0.12345678345 as TINYINT)");
+  BENCHMARK("decimal16_to_tinyint", "cast(78.12345678123456783456789 as TINYINT)");
+  BENCHMARK("decimal4_to_smallint", "cast(78.5 as SMALLINT)");
+  BENCHMARK("decimal8_to_smallint", "cast(0.12345678345 as SMALLINT)");
+  BENCHMARK("decimal16_to_smallint", "cast(78.12345678123456783456789 as SMALLINT)");
+  BENCHMARK("decimal4_to_int", "cast(12345678.5 as INT)");
+  BENCHMARK("decimal8_to_int", "cast(12345678.345 as INT)");
+  BENCHMARK("decimal16_to_int", "cast(12345678.123456783456789 as INT)");
+  BENCHMARK("decimal4_to_bigint", "cast(12345678.5 as BIGINT)");
+  BENCHMARK("decimal8_to_bigint", "cast(12345678.345 as BIGINT)");
+  BENCHMARK("decimal16_to_bigint", "cast(12345678.123456783456789 as BIGINT)");
+  BENCHMARK("decimal4_to_float", "cast(12345678.5 as FLOAT)");
+  BENCHMARK("decimal8_to_float", "cast(12345678.345 as FLOAT)");
+  BENCHMARK("decimal16_to_float", "cast(12345678.123456783456789 as FLOAT)");
+  BENCHMARK("decimal4_to_double", "cast(12345678.5 as DOUBLE)");
+  BENCHMARK("decimal8_to_double", "cast(12345678.345 as DOUBLE)");
+  BENCHMARK("decimal16_to_double", "cast(12345678.123456783456789 as DOUBLE)");
+  BENCHMARK("decimal4_to_string", "cast(12345678.5 as STRING)");
+  BENCHMARK("decimal8_to_string", "cast(12345678.345 as STRING)");
+  BENCHMARK("decimal16_to_string", "cast(12345678.123456783456789 as STRING)");
   return suite;
 }
 
-// ConditionalFunctions: Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                       not_null               877.8                  1X
-//                        is null               938.3              1.069X
-//                       compound               240.2             0.2736X
-//                    int_between                 191             0.2176X
-//              timestamp_between                18.5            0.02108X
-//                 string_between               93.94              0.107X
-//                        bool_in               356.6             0.4063X
-//                         int_in               209.7             0.2389X
-//                       float_in               216.4             0.2465X
-//                      string_in               120.1             0.1368X
-//                   timestamp_in               19.79            0.02255X
-//                         if_int               506.8             0.5773X
-//                      if_string               470.6             0.5361X
-//                   if_timestamp               70.19            0.07996X
-//                  coalesce_bool               194.2             0.2213X
-//                       case_int                 259             0.2951X
-Benchmark* BenchmarkConditionalFunctions() {
-// TODO: expand these cases when the parser issues are fixed (see corresponding tests
-// in expr-test).
-  Benchmark* suite = new Benchmark("ConditionalFunctions");
+// ConditionalFn:             Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                            not_null                353      357      359         1X         1X         1X
+//                             is null                334      337      340     0.946X     0.944X     0.947X
+//                            compound                300      303      305     0.851X     0.849X      0.85X
+//                         int_between                154      155      156     0.437X     0.435X     0.436X
+//                   timestamp_between               8.79     8.87     8.87    0.0249X    0.0248X    0.0247X
+//                      string_between                128      129      130     0.364X     0.361X     0.362X
+//                             bool_in                249      251      253     0.706X     0.703X     0.705X
+//                              int_in                247      248      249     0.699X     0.695X     0.695X
+//                            float_in                227      228      230     0.643X     0.638X      0.64X
+//                           string_in                161      162      163     0.456X     0.453X     0.455X
+//                        timestamp_in               9.35     9.35     9.35    0.0265X    0.0262X    0.0261X
+//                              if_int                401      404      407      1.14X      1.13X      1.13X
+//                           if_string                363      366      369      1.03X      1.03X      1.03X
+//                        if_timestamp               37.9     38.2     38.3     0.107X     0.107X     0.107X
+//                       coalesce_bool                201      202      204     0.569X     0.567X     0.568X
+//                            case_int                104      105      106     0.295X     0.294X     0.295X
+//
+// ConditionalFnCodegen:      Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                            not_null                822      828      835         1X         1X         1X
+//                             is null                819      824      829     0.996X     0.995X     0.993X
+//                            compound                820      827      832     0.997X     0.998X     0.997X
+//                         int_between                819      826      832     0.996X     0.997X     0.997X
+//                   timestamp_between               11.4     11.4     11.5    0.0138X    0.0138X    0.0137X
+//                      string_between                825      831      836         1X         1X         1X
+//                             bool_in                474      477      482     0.577X     0.576X     0.577X
+//                              int_in                561      566      570     0.682X     0.684X     0.682X
+//                            float_in                563      565      569     0.684X     0.683X     0.682X
+//                           string_in                352      355      357     0.428X     0.429X     0.428X
+//                        timestamp_in               11.9       12       12    0.0144X    0.0145X    0.0144X
+//                              if_int                777      783      789     0.945X     0.945X     0.945X
+//                           if_string                778      783      789     0.947X     0.946X     0.945X
+//                        if_timestamp                 45     45.2     45.4    0.0547X    0.0546X    0.0544X
+//                       coalesce_bool                823      828      835         1X         1X         1X
+//                            case_int                771      776      781     0.937X     0.937X     0.935X
+Benchmark* BenchmarkConditionalFunctions(bool codegen) {
+  // TODO: expand these cases when the parser issues are fixed (see corresponding tests
+  // in expr-test).
+  Benchmark* suite = new Benchmark(BenchmarkName("ConditionalFn", codegen));
   BENCHMARK("not_null", "!NULL");
   BENCHMARK("is null", "5 IS NOT NULL");
   BENCHMARK("compound", "(TRUE && TRUE) || FALSE");
@@ -326,36 +518,67 @@ Benchmark* BenchmarkConditionalFunctions() {
   return suite;
 }
 
-// StringFunctions:      Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                         length               920.2                  1X
-//                     substring1               351.4             0.3819X
-//                     substring2               327.9             0.3563X
-//                           left               508.6             0.5527X
-//                          right               508.2             0.5522X
-//                          lower               103.9             0.1129X
-//                          upper               103.2             0.1121X
-//                        reverse               324.9             0.3531X
-//                           trim               421.2             0.4578X
-//                          ltrim               526.6             0.5723X
-//                          rtrim               566.5             0.6156X
-//                          space               94.63             0.1028X
-//                          ascii                1048              1.139X
-//                          instr               175.6             0.1909X
-//                         locate               184.7             0.2007X
-//                        locate2               175.8             0.1911X
-//                         concat               109.5              0.119X
-//                        concat2               75.83            0.08241X
-//                       concatws               143.4             0.1559X
-//                      concatws2               70.38            0.07649X
-//                         repeat               98.54             0.1071X
-//                           lpad               154.7             0.1681X
-//                           rpad               145.6             0.1582X
-//                    find_in_set               83.38            0.09061X
-//                 regexp_extract                6.42           0.006977X
-//                 regexp_replace              0.7435           0.000808X
-Benchmark* BenchmarkStringFunctions() {
-  Benchmark* suite = new Benchmark("StringFunctions");
+// StringFn:                  Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                              length                209      210      212         1X         1X         1X
+//                          substring1                153      153      154      0.73X     0.729X     0.727X
+//                          substring2                173      174      176     0.827X     0.826X      0.83X
+//                                left                159      160      161     0.763X     0.762X     0.758X
+//                               right                160      160      161     0.764X     0.763X     0.758X
+//                               lower               74.9     75.6     76.3     0.358X      0.36X      0.36X
+//                               upper               76.5     77.4       78     0.366X     0.369X     0.368X
+//                             reverse                108      109      110     0.515X     0.519X      0.52X
+//                                trim                194      195      197      0.93X      0.93X     0.929X
+//                               ltrim                217      218      221      1.04X      1.04X      1.04X
+//                               rtrim                217      220      221      1.04X      1.05X      1.04X
+//                               space                147      148      149     0.702X     0.704X     0.703X
+//                               ascii                294      296      298      1.41X      1.41X      1.41X
+//                               instr               95.1     95.5     96.5     0.455X     0.455X     0.455X
+//                              locate               93.7     94.1     94.6     0.448X     0.448X     0.446X
+//                             locate2               98.8       99     99.5     0.473X     0.471X     0.469X
+//                              concat                129      130      131     0.616X     0.618X     0.618X
+//                             concat2               99.4      100      102     0.475X     0.478X     0.479X
+//                            concatws                262      264      267      1.25X      1.26X      1.26X
+//                           concatws2               97.5     98.4     99.2     0.467X     0.468X     0.468X
+//                              repeat               83.8     84.9     85.6     0.401X     0.404X     0.403X
+//                                lpad                 81     81.7     82.2     0.387X     0.389X     0.388X
+//                                rpad               81.5     82.4     82.7      0.39X     0.392X      0.39X
+//                         find_in_set                140      142      143      0.67X     0.674X     0.673X
+//                      regexp_extract               19.9     20.1     20.1    0.0953X    0.0957X    0.0949X
+//                      regexp_replace               1.43     1.44     1.44   0.00686X   0.00687X    0.0068X
+//
+// StringFnCodegen:           Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                              length                826      834      836         1X         1X         1X
+//                          substring1                297      300      302      0.36X      0.36X     0.362X
+//                          substring2                777      785      790     0.941X     0.942X     0.945X
+//                                left                296      299      301     0.359X     0.359X      0.36X
+//                               right                297      300      303      0.36X     0.359X     0.362X
+//                               lower                102      103      104     0.123X     0.123X     0.125X
+//                               upper                105      106      107     0.127X     0.127X     0.128X
+//                             reverse                161      165      168     0.194X     0.198X       0.2X
+//                                trim                425      427      432     0.514X     0.513X     0.517X
+//                               ltrim                561      564      569     0.679X     0.677X     0.681X
+//                               rtrim                584      587      594     0.707X     0.705X     0.711X
+//                               space                213      215      217     0.258X     0.258X      0.26X
+//                               ascii                822      829      836     0.996X     0.994X         1X
+//                               instr                215      217      219     0.261X      0.26X     0.262X
+//                              locate                214      217      218     0.259X      0.26X     0.261X
+//                             locate2                226      228      230     0.274X     0.274X     0.275X
+//                              concat                210      214      216     0.254X     0.257X     0.258X
+//                             concat2                189      191      193     0.229X      0.23X     0.231X
+//                            concatws                777      784      790     0.941X     0.941X     0.945X
+//                           concatws2                160      162      163     0.194X     0.194X     0.196X
+//                              repeat                159      161      164     0.193X     0.194X     0.196X
+//                                lpad                212      214      216     0.257X     0.257X     0.258X
+//                                rpad                212      214      216     0.257X     0.257X     0.259X
+//                         find_in_set                276      278      280     0.334X     0.333X     0.335X
+//                      regexp_extract               20.4     20.5     20.8    0.0247X    0.0246X    0.0248X
+//                      regexp_replace               1.43     1.47     1.47   0.00174X   0.00176X   0.00176X
+Benchmark* BenchmarkStringFunctions(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("StringFn", codegen));
   BENCHMARK("length", "length('Hello World!')");
   BENCHMARK("substring1", "substring('Hello World!', 5)");
   BENCHMARK("substring2", "substring('Hello World!', 5, 5)");
@@ -385,18 +608,31 @@ Benchmark* BenchmarkStringFunctions() {
   return suite;
 }
 
-// UrlFunctions:         Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                      authority               118.1                  1X
-//                           file               95.52              0.809X
-//                           host               94.52             0.8005X
-//                           path               98.63             0.8353X
-//                       protocol               36.29             0.3073X
-//                           user               121.1              1.026X
-//                      user_info               121.4              1.029X
-//                     query_name               41.34             0.3501X
-Benchmark* BenchmarkUrlFunctions() {
-  Benchmark* suite = new Benchmark("UrlFunctions");
+// UrlFn:                     Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                           authority                113      114      114         1X         1X         1X
+//                                file               93.7     94.3     94.6     0.829X     0.828X     0.827X
+//                                host               90.2     90.6       91     0.798X     0.797X     0.796X
+//                                path                104      105      106     0.924X     0.924X     0.923X
+//                            protocol                112      112      113     0.989X     0.988X     0.986X
+//                                user                105      105      106     0.925X     0.924X     0.923X
+//                           user_info               93.2     93.8     94.2     0.825X     0.825X     0.823X
+//                          query_name               44.4     44.5     44.8     0.393X     0.391X     0.392X
+//
+// UrlFnCodegen:              Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                           authority                158      159      160         1X         1X         1X
+//                                file                123      124      125      0.78X      0.78X     0.781X
+//                                host                132      133      133     0.832X     0.834X     0.835X
+//                                path                142      143      144     0.899X     0.899X     0.899X
+//                            protocol                159      160      160      1.01X         1X         1X
+//                                user                138      139      139     0.871X     0.871X     0.871X
+//                           user_info                143      144      144     0.902X     0.902X     0.901X
+//                          query_name               49.9     50.1     50.3     0.316X     0.315X     0.315X
+Benchmark* BenchmarkUrlFunctions(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("UrlFn", codegen));
   BENCHMARK("authority", "parse_url('http://user:pass@example.com:80/docs/books/tutorial/"
       "index.html?name=networking#DOWNLOADING', 'AUTHORITY')");
   BENCHMARK("file", "parse_url('http://example.com/docs/books/tutorial/"
@@ -405,7 +641,8 @@ Benchmark* BenchmarkUrlFunctions() {
       "index.html?name=networking#DOWNLOADING', 'HOST')");
   BENCHMARK("path", "parse_url('http://user:pass@example.com/docs/books/tutorial/"
       "index.html?name=networking#DOWNLOADING', 'PATH')");
-  BENCHMARK("protocol", "parse_url('user:pass@example.com/docs/books/tutorial/"
+  BENCHMARK("protocol",
+      "parse_url('http://user:pass@example.com/docs/books/tutorial/"
       "index.html?name=networking#DOWNLOADING', 'PROTOCOL')");
   BENCHMARK("user", "parse_url('http://user@example.com/docs/books/tutorial/"
         "index.html?name=networking#DOWNLOADING', 'USERINFO')");
@@ -416,42 +653,79 @@ Benchmark* BenchmarkUrlFunctions() {
   return suite;
 }
 
-// MathFunctions:        Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                             pi                1642                  1X
-//                              e                1546             0.9416X
-//                            abs                 877             0.5342X
-//                             ln               110.7            0.06744X
-//                          log10               88.48             0.0539X
-//                           log2               108.3            0.06597X
-//                            log               55.61            0.03387X
-//                            pow               53.93            0.03285X
-//                           sqrt               629.6             0.3835X
-//                           sign                 732             0.4459X
-//                            sin               176.3             0.1074X
-//                           asin               169.6             0.1033X
-//                            cos               156.3             0.0952X
-//                           acos               167.5              0.102X
-//                            tan               176.3             0.1074X
-//                           atan               153.8            0.09371X
-//                        radians               601.5             0.3664X
-//                        degrees               601.5             0.3664X
-//                            bin                  45            0.02741X
-//                       pmod_int               147.3            0.08976X
-//                     pmod_float               172.9             0.1053X
-//                       positive                 877             0.5342X
-//                       negative               936.9             0.5707X
-//                           ceil               466.7             0.2843X
-//                          floor               390.9             0.2381X
-//                          round               820.5             0.4998X
-//                         round2               220.2             0.1341X
-//                        hex_int               5.745             0.0035X
-//                     hex_string               4.441           0.002705X
-//                          unhex               3.394           0.002067X
-//                       conv_int               33.15            0.02019X
-//                    conv_string                36.6            0.02229X
-Benchmark* BenchmarkMathFunctions() {
-  Benchmark* suite = new Benchmark("MathFunctions");
+// MathFn:                    Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                                  pi                329      330      334         1X         1X         1X
+//                                   e                339      343      346      1.03X      1.04X      1.04X
+//                                 abs                144      145      146     0.438X     0.438X     0.437X
+//                                  ln                126      127      128     0.383X     0.385X     0.384X
+//                               log10                116      116      118     0.352X     0.351X     0.352X
+//                                log2                131      131      132     0.397X     0.397X     0.394X
+//                                 log               85.6     85.9     86.2      0.26X      0.26X     0.258X
+//                                 pow               62.7     62.9     63.2     0.191X      0.19X     0.189X
+//                                sqrt                315      318      320     0.957X     0.962X     0.958X
+//                                sign                320      324      325     0.972X     0.981X     0.973X
+//                                 sin                146      147      148     0.443X     0.444X     0.444X
+//                                asin                244      247      250     0.741X     0.747X     0.748X
+//                                 cos                134      135      136     0.407X     0.407X     0.407X
+//                                acos                250      251      255     0.759X      0.76X     0.762X
+//                                 tan                151      152      154     0.459X     0.459X      0.46X
+//                                atan                136      137      138     0.414X     0.415X     0.413X
+//                             radians                331      334      336         1X      1.01X         1X
+//                             degrees                310      312      315     0.942X     0.943X     0.943X
+//                                 bin               94.7     95.7     96.1     0.288X      0.29X     0.288X
+//                            pmod_int                118      118      120     0.359X     0.358X     0.359X
+//                          pmod_float                121      121      122     0.367X     0.367X     0.366X
+//                            positive                308      310      313     0.937X     0.938X     0.936X
+//                            negative                322      326      328     0.978X     0.986X     0.981X
+//                                ceil               62.1     62.3       63     0.189X     0.189X     0.189X
+//                               floor               58.3     58.6     58.9     0.177X     0.177X     0.176X
+//                               round               60.6     61.1     61.4     0.184X     0.185X     0.184X
+//                              round2               57.7     58.4     58.7     0.175X     0.177X     0.176X
+//                             hex_int                8.6     8.68     8.68    0.0262X    0.0263X     0.026X
+//                          hex_string               6.42     6.42     6.52    0.0195X    0.0194X    0.0195X
+//                               unhex               4.81     4.81     4.81    0.0146X    0.0146X    0.0144X
+//                            conv_int               57.8     58.2     58.5     0.176X     0.176X     0.175X
+//                         conv_string               58.4     58.9     59.3     0.177X     0.178X     0.178X
+//
+// MathFnCodegen:             Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                                  pi                777      786      791         1X         1X         1X
+//                                   e                778      783      791         1X     0.996X         1X
+//                                 abs                609      615      620     0.784X     0.782X     0.783X
+//                                  ln                778      785      789         1X     0.999X     0.998X
+//                               log10                778      783      793         1X     0.996X         1X
+//                                log2                778      782      790         1X     0.995X     0.999X
+//                                 log                777      785      787         1X     0.998X     0.995X
+//                                 pow                777      784      790     0.999X     0.997X     0.999X
+//                                sqrt                779      783      791         1X     0.996X         1X
+//                                sign                777      786      791         1X         1X         1X
+//                                 sin                778      784      790         1X     0.997X     0.999X
+//                                asin                379      382      386     0.487X     0.487X     0.488X
+//                                 cos                778      784      791         1X     0.998X         1X
+//                                acos                391      393      397     0.503X       0.5X     0.502X
+//                                 tan                778      785      790         1X     0.999X     0.999X
+//                                atan                216      218      219     0.278X     0.277X     0.277X
+//                             radians                777      784      790     0.999X     0.998X     0.998X
+//                             degrees                779      784      789         1X     0.997X     0.998X
+//                                 bin                166      168      170     0.214X     0.214X     0.215X
+//                            pmod_int                777      784      789         1X     0.997X     0.997X
+//                          pmod_float                778      783      792         1X     0.996X         1X
+//                            positive                778      783      792         1X     0.996X         1X
+//                            negative                778      782      790         1X     0.995X     0.999X
+//                                ceil                609      614      620     0.784X     0.781X     0.783X
+//                               floor                608      614      619     0.782X     0.781X     0.782X
+//                               round                610      612      617     0.785X     0.778X      0.78X
+//                              round2                608      613      619     0.782X     0.781X     0.782X
+//                             hex_int               8.79     8.87     8.87    0.0113X    0.0113X    0.0112X
+//                          hex_string               6.74     6.79     6.79   0.00868X   0.00864X   0.00859X
+//                               unhex                  5        5        5   0.00643X   0.00636X   0.00632X
+//                            conv_int                170      171      173     0.219X     0.218X     0.219X
+//                         conv_string                189      191      193     0.243X     0.243X     0.244X
+Benchmark* BenchmarkMathFunctions(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("MathFn", codegen));
   BENCHMARK("pi", "pi()");
   BENCHMARK("e", "e()");
   BENCHMARK("abs", "abs(-1.0)");
@@ -487,37 +761,77 @@ Benchmark* BenchmarkMathFunctions() {
   return suite;
 }
 
-// TimestampFunctions:   Function                Rate          Comparison
-// ----------------------------------------------------------------------
-//                        literal               68.18                  1X
-//                      to_string               1.131            0.01659X
-//                       add_year               34.57              0.507X
-//                      sub_month               33.04             0.4846X
-//                      add_weeks               56.15             0.8236X
-//                       sub_days               57.21             0.8391X
-//                            add               55.85             0.8191X
-//                      sub_hours               44.44             0.6519X
-//                    add_minutes               43.96             0.6448X
-//                    sub_seconds               42.78             0.6274X
-//                      add_milli               43.43             0.6371X
-//                      sub_micro               43.88             0.6436X
-//                       add_nano               41.83             0.6135X
-//                unix_timestamp1               32.74             0.4803X
-//                unix_timestamp2               39.39             0.5778X
-//                     from_unix1               1.192            0.01748X
-//                     from_unix2               1.602             0.0235X
-//                           year                73.4              1.077X
-//                          month               72.53              1.064X
-//                   day of month               71.98              1.056X
-//                    day of year               56.67             0.8312X
-//                   week of year               50.68             0.7433X
-//                           hour               100.1              1.468X
-//                         minute               97.18              1.425X
-//                         second                96.7              1.418X
-//                        to date               3.075            0.04511X
-//                      date diff               39.54             0.5799X
-Benchmark* BenchmarkTimestampFunctions() {
-  Benchmark* suite = new Benchmark("TimestampFunctions");
+// TimestampFn:               Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                             literal               34.4     34.6     34.8         1X         1X         1X
+//                           to_string               2.09     2.12     2.12    0.0609X    0.0611X    0.0607X
+//                            add_year               16.7     16.7     16.8     0.485X     0.481X     0.482X
+//                           sub_month               16.5     16.5     16.6      0.48X     0.476X     0.477X
+//                           add_weeks               20.9     20.9     21.1     0.609X     0.604X     0.605X
+//                            sub_days               19.7     19.7     19.8     0.574X      0.57X     0.569X
+//                                 add               20.7     20.9     21.1     0.604X     0.604X     0.605X
+//                           sub_hours               19.4     19.5     19.6     0.563X     0.564X     0.563X
+//                         add_minutes               19.9     19.9       20      0.58X     0.575X     0.575X
+//                         sub_seconds               19.9     19.9       20      0.58X     0.575X     0.574X
+//                           add_milli               18.3     18.3     18.5     0.534X     0.529X      0.53X
+//                           sub_micro               18.3     18.3     18.5     0.534X     0.529X      0.53X
+//                            add_nano               18.7     18.9       19     0.544X     0.545X     0.546X
+//                     unix_timestamp1               38.7     38.9     39.1      1.13X      1.12X      1.12X
+//                     unix_timestamp2                 53     53.3     53.5      1.54X      1.54X      1.54X
+//                          from_unix1               6.11     6.11     6.19     0.178X     0.176X     0.178X
+//                          from_unix2               10.7     10.9     11.2     0.312X     0.316X     0.321X
+//                                year               38.9     39.1     39.3      1.13X      1.13X      1.13X
+//                               month               39.1     39.3     39.5      1.14X      1.13X      1.13X
+//                        day of month               38.7     38.7     38.9      1.13X      1.12X      1.12X
+//                         day of year               34.6     34.8     34.8      1.01X      1.01X         1X
+//                        week of year               33.3     33.6     33.8      0.97X     0.971X      0.97X
+//                                hour               76.7     77.4     78.4      2.23X      2.24X      2.25X
+//                              minute               76.5       77     78.1      2.23X      2.22X      2.24X
+//                              second               74.6     75.4     76.4      2.17X      2.18X      2.19X
+//                             to date                 19     19.1     19.2     0.554X     0.551X     0.552X
+//                           date diff               17.5     17.5     17.6     0.509X     0.505X     0.505X
+//                            from utc               22.1     22.4     22.4     0.644X     0.646X     0.644X
+//                              to utc               18.9     18.9       19      0.55X     0.545X     0.546X
+//                                 now                290      293      295      8.44X      8.47X      8.48X
+//                      unix_timestamp                209      211      213      6.09X      6.08X      6.11X
+//
+// TimestampFnCodegen:        Function  iters/ms   10%ile   50%ile   90%ile     10%ile     50%ile     90%ile
+//                                                                          (relative) (relative) (relative)
+// ---------------------------------------------------------------------------------------------------------
+//                             literal               37.2     37.4     37.5         1X         1X         1X
+//                           to_string               2.14     2.16     2.16    0.0576X    0.0577X    0.0575X
+//                            add_year               18.5     18.5     18.7     0.498X     0.495X     0.497X
+//                           sub_month               18.3     18.3     18.5     0.493X      0.49X     0.492X
+//                           add_weeks               23.9       24     24.1     0.641X     0.641X     0.641X
+//                            sub_days               22.1     22.1     22.3     0.595X     0.592X     0.593X
+//                                 add               23.6     23.6     23.8     0.634X     0.631X     0.634X
+//                           sub_hours               21.9     21.9       22      0.59X     0.587X     0.587X
+//                         add_minutes               22.4     22.6     22.7     0.602X     0.604X     0.606X
+//                         sub_seconds               22.4     22.4     22.6     0.602X     0.599X     0.602X
+//                           add_milli               20.6     20.6     20.7     0.552X      0.55X     0.552X
+//                           sub_micro               20.6     20.7     20.9     0.552X     0.554X     0.556X
+//                            add_nano               21.1     21.3     21.4     0.567X     0.568X      0.57X
+//                     unix_timestamp1               46.9     46.9     47.1      1.26X      1.25X      1.25X
+//                     unix_timestamp2               64.2     64.4     64.7      1.72X      1.72X      1.72X
+//                          from_unix1                6.3      6.3     6.37     0.169X     0.168X      0.17X
+//                          from_unix2               11.3     11.6     11.8     0.305X     0.309X     0.315X
+//                                year               59.3     59.4     59.8      1.59X      1.59X      1.59X
+//                               month               59.3     59.4     59.7      1.59X      1.59X      1.59X
+//                        day of month               58.8     59.3     59.6      1.58X      1.58X      1.59X
+//                         day of year               53.4     53.5     53.8      1.44X      1.43X      1.43X
+//                        week of year               50.4     50.6     51.2      1.35X      1.35X      1.36X
+//                                hour                126      127      129      3.38X       3.4X      3.44X
+//                              minute                126      126      129      3.38X      3.38X      3.43X
+//                              second                126      127      128      3.38X       3.4X      3.42X
+//                             to date               23.1     23.1     23.4     0.622X     0.619X     0.623X
+//                           date diff               22.4     22.4     22.6     0.602X     0.599X     0.601X
+//                            from utc               38.9     39.4     39.6      1.05X      1.05X      1.06X
+//                              to utc               21.8     21.8     21.9     0.585X     0.582X     0.582X
+//                                 now                517      522      527      13.9X        14X        14X
+//                      unix_timestamp                378      381      384      10.2X      10.2X      10.2X
+Benchmark* BenchmarkTimestampFunctions(bool codegen) {
+  Benchmark* suite = new Benchmark(BenchmarkName("TimestampFn", codegen));
   BENCHMARK("literal", "cast('2012-01-01 09:10:11.123456789' as timestamp)");
   BENCHMARK("to_string",
       "cast(cast('2012-01-01 09:10:11.123456789' as timestamp) as string)");
@@ -561,50 +875,55 @@ Benchmark* BenchmarkTimestampFunctions() {
       "to_date(cast('2011-12-22 09:10:11.12345678' as timestamp))");
   BENCHMARK("date diff", "datediff(cast('2011-12-22 09:10:11.12345678' as timestamp), "
       "cast('2012-12-22' as timestamp))");
-#if 0
-  // TODO: need to create a valid runtime state for these functions
   BENCHMARK("from utc",
       "from_utc_timestamp(cast(1.3041352164485E9 as timestamp), 'PST')");
   BENCHMARK("to utc",
       "to_utc_timestamp(cast('2011-01-01 01:01:01' as timestamp), 'PST')");
   BENCHMARK("now", "now()");
   BENCHMARK("unix_timestamp", "unix_timestamp()");
-#endif
   return suite;
 }
 
+typedef Benchmark* (*SingleBenchmark)(bool);
+
 int main(int argc, char** argv) {
   impala::InitCommonRuntime(argc, argv, true, impala::TestInfo::BE_TEST);
   impala::InitFeSupport(false);
   ABORT_IF_ERROR(impala::LlvmCodeGen::InitializeLlvm());
+  ThreadDebugInfo debugInfo;
+
+  // The host running this test might have an out-of-date tzdata package installed.
+  // To avoid tzdata related issues, we will load time-zone db from the testdata
+  // directory.
+  FLAGS_hdfs_zone_info_zip =
+      Substitute("file://$0/testdata/tzdb/2017c.zip", getenv("IMPALA_HOME"));
+  ABORT_IF_ERROR(TimezoneDatabase::Initialize());
 
   // Dynamically construct at runtime as the planner initialization depends on
   // static objects being initialized in other compilation modules.
   planner = new Planner();
 
-  // Generate all the tests first (this does the planning)
-  Benchmark* literals = BenchmarkLiterals();
-  Benchmark* arithmetics = BenchmarkArithmetic();
-  Benchmark* like = BenchmarkLike();
-  Benchmark* cast = BenchmarkCast();
-  Benchmark* decimal_cast = BenchmarkDecimalCast();
-  Benchmark* conditional_fns = BenchmarkConditionalFunctions();
-  Benchmark* string_fns = BenchmarkStringFunctions();
-  Benchmark* url_fns = BenchmarkUrlFunctions();
-  Benchmark* math_fns = BenchmarkMathFunctions();
-  Benchmark* timestamp_fns = BenchmarkTimestampFunctions();
+  // List benchmark functions that will be exercised.
+  vector<SingleBenchmark> benchmarks;
+  benchmarks.push_back(&BenchmarkLiterals);
+  benchmarks.push_back(&BenchmarkArithmetic);
+  benchmarks.push_back(&BenchmarkLike);
+  benchmarks.push_back(&BenchmarkCast);
+  benchmarks.push_back(&BenchmarkDecimalCast);
+  benchmarks.push_back(&BenchmarkConditionalFunctions);
+  benchmarks.push_back(&BenchmarkStringFunctions);
+  benchmarks.push_back(&BenchmarkUrlFunctions);
+  benchmarks.push_back(&BenchmarkMathFunctions);
+  benchmarks.push_back(&BenchmarkTimestampFunctions);
 
   cout << Benchmark::GetMachineInfo() << endl;
-  cout << literals->Measure() << endl;
-  cout << arithmetics->Measure() << endl;
-  cout << like->Measure() << endl;
-  cout << cast->Measure() << endl;
-  cout << decimal_cast->Measure() << endl;
-  cout << conditional_fns->Measure() << endl;
-  cout << string_fns->Measure() << endl;
-  cout << url_fns->Measure() << endl;
-  cout << math_fns->Measure() << endl;
-  cout << timestamp_fns->Measure() << endl;
+  for (auto& benchmark : benchmarks) {
+    for (int codegen = 0; codegen <= 1; codegen++) {
+      planner->EnableCodegen(codegen);
+      Benchmark* suite = (*benchmark)(codegen);
+      cout << suite->Measure() << endl;
+    }
+  }
 
   return 0;
 }