Skip to content
Snippets Groups Projects
Unverified Commit 8eb25e5b authored by Oleksandr Yakushev's avatar Oleksandr Yakushev Committed by GitHub
Browse files

perf: Miscellaneous card rendering improvements (#47679)

* perf: Optimize reading rows into vectors in JDBC driver

* perf: Use direct interop when computing with-time-zone-same-instant
parent d74fbe95
No related branches found
No related tags found
No related merge requests found
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
[metabase.util.i18n :refer [tru]] [metabase.util.i18n :refer [tru]]
[metabase.util.log :as log] [metabase.util.log :as log]
[metabase.util.malli :as mu] [metabase.util.malli :as mu]
[metabase.util.performance :as perf]
[potemkin :as p]) [potemkin :as p])
(:import (:import
(java.sql Connection JDBCType PreparedStatement ResultSet ResultSetMetaData SQLFeatureNotSupportedException (java.sql Connection JDBCType PreparedStatement ResultSet ResultSetMetaData SQLFeatureNotSupportedException
...@@ -634,11 +635,11 @@ ...@@ -634,11 +635,11 @@
"Returns a thunk that can be called repeatedly to get the next row in the result set, using appropriate methods to "Returns a thunk that can be called repeatedly to get the next row in the result set, using appropriate methods to
fetch each value in the row. Returns `nil` when the result set has no more rows." fetch each value in the row. Returns `nil` when the result set has no more rows."
[driver ^ResultSet rs ^ResultSetMetaData rsmeta] [driver ^ResultSet rs ^ResultSetMetaData rsmeta]
(let [fns (for [i (column-range rsmeta)] (let [fns (mapv #(read-column-thunk driver rs rsmeta (long %))
(read-column-thunk driver rs rsmeta (long i)))] (column-range rsmeta))]
(log-readers driver rsmeta fns) (log-readers driver rsmeta fns)
(let [thunk (if (seq fns) (let [thunk (if (seq fns)
(apply juxt fns) (perf/juxt* fns)
(constantly []))] (constantly []))]
(fn row-thunk* [] (fn row-thunk* []
(when (.next rs) (when (.next rs)
......
...@@ -514,6 +514,8 @@ ...@@ -514,6 +514,8 @@
converts it to the corresponding offset/zoned type; for offset/zoned types, this applies an appropriate timezone converts it to the corresponding offset/zoned type; for offset/zoned types, this applies an appropriate timezone
shift.")) shift."))
(def ^:private local-time-0 (t/local-time 0))
(extend-protocol WithTimeZoneSameInstant (extend-protocol WithTimeZoneSameInstant
;; convert to a OffsetTime with no offset (UTC); the OffsetTime method impl will apply the zone shift. ;; convert to a OffsetTime with no offset (UTC); the OffsetTime method impl will apply the zone shift.
LocalTime LocalTime
...@@ -526,15 +528,11 @@ ...@@ -526,15 +528,11 @@
LocalDate LocalDate
(with-time-zone-same-instant [t zone-id] (with-time-zone-same-instant [t zone-id]
(t/offset-date-time t (t/local-time 0) zone-id)) (with-time-zone-same-instant (LocalDateTime/of t local-time-0) zone-id))
LocalDate
(with-time-zone-same-instant [t zone-id]
(t/offset-date-time t (t/local-time 0) zone-id))
LocalDateTime LocalDateTime
(with-time-zone-same-instant [t zone-id] (with-time-zone-same-instant [t ^java.time.ZoneId zone-id]
(t/offset-date-time t zone-id)) (OffsetDateTime/of t (.getOffset (.getRules zone-id) t)))
;; instants are always normalized to UTC, so don't make any changes here. If you want to format in a different zone, ;; instants are always normalized to UTC, so don't make any changes here. If you want to format in a different zone,
;; convert to an OffsetDateTime or ZonedDateTime first. ;; convert to an OffsetDateTime or ZonedDateTime first.
......
...@@ -69,3 +69,14 @@ ...@@ -69,3 +69,14 @@
(persistent! (reduce #(conj! %1 (f %2 %3 %4)) (transient []) coll1 coll2 coll3))) (persistent! (reduce #(conj! %1 (f %2 %3 %4)) (transient []) coll1 coll2 coll3)))
([f coll1 coll2 coll3 coll4] ([f coll1 coll2 coll3 coll4]
(persistent! (reduce #(conj! %1 (f %2 %3 %4 %5)) (transient []) coll1 coll2 coll3 coll4)))) (persistent! (reduce #(conj! %1 (f %2 %3 %4 %5)) (transient []) coll1 coll2 coll3 coll4))))
(defn juxt*
"Like `clojure.core/juxt`, but accepts a list of functions instead of varargs. Uses more efficient mapping."
[fns]
(let [fns (vec fns)]
(fn
([] (mapv #(%) fns))
([x] (mapv #(% x) fns))
([x y] (mapv #(% x y) fns))
([x y z] (mapv #(% x y z) fns))
([x y z & args] (mapv #(apply % x y z args) fns)))))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment