You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by GitBox <gi...@apache.org> on 2019/05/18 13:59:24 UTC

[GitHub] [spark] mgaido91 opened a new pull request #24636: [SPARK-27684][SQL] Avoid conversion overhead for primitive types

mgaido91 opened a new pull request #24636: [SPARK-27684][SQL] Avoid conversion overhead for primitive types
URL: https://github.com/apache/spark/pull/24636
 
 
   ## What changes were proposed in this pull request?
   
   As outlined in the JIRA by @JoshRosen, our conversion mechanism from catalyst types to scala ones is pretty inefficient for primitive data types. Indeed, in these cases, most of the times we are adding useless calls to `identity` function or anyway to functions which return the same value. Using the information we have when we generate the code, we can avoid most of these overheads.
   
   ## How was this patch tested?
   
   Here is a simple test which shows the benefit that this PR can bring:
   ```
   test("SPARK-27684: perf evaluation") {
       val intLongUdf = ScalaUDF(
         (a: Int, b: Long) => a + b, LongType,
         Literal(1) :: Literal(1L) :: Nil,
         true :: true :: Nil,
         nullable = false)
   
       val plan = generateProject(
         MutableProjection.create(Alias(intLongUdf, s"udf")() :: Nil),
         intLongUdf)
       plan.initialize(0)
   
       var i = 0
       val N = 100000000
       val t0 = System.nanoTime()
       while(i < N) {
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         plan(EmptyRow).get(0, intLongUdf.dataType)
         i += 1
       }
       val t1 = System.nanoTime()
       println(s"Avg time: ${(t1 - t0).toDouble / N} ns")
     }
   ```
   The output before the patch is:
   ```
   Avg time: 51.27083294 ns
   ```
   after, we get:
   ```
   Avg time: 11.85874227 ns
   ```
   which is ~5X faster.
   
   Moreover a benchmark has been added for Scala UDF. The output after the patch can be seen in this PR, before the patch, the output was:
   ```
   ================================================================================================
   UDF with mixed input types
   ================================================================================================
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int/string to string:       Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int/string to string wholestage off            257            287          42          0,4        2569,5       1,0X
   long/nullable int/string to string wholestage on            158            172          18          0,6        1579,0       1,6X
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int/string to option:       Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int/string to option wholestage off            104            107           5          1,0        1037,9       1,0X
   long/nullable int/string to option wholestage on             80             92          12          1,2         804,0       1,3X
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int to primitive:           Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int to primitive wholestage off             71             76           7          1,4         712,1       1,0X
   long/nullable int to primitive wholestage on             64             71           6          1,6         636,2       1,1X
   
   
   ================================================================================================
   UDF with primitive types
   ================================================================================================
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int to string:              Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int to string wholestage off             60             60           0          1,7         600,3       1,0X
   long/nullable int to string wholestage on             55             64           8          1,8         551,2       1,1X
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int to option:              Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int to option wholestage off             66             73           9          1,5         663,0       1,0X
   long/nullable int to option wholestage on             30             32           2          3,3         300,7       2,2X
   
   Java HotSpot(TM) 64-Bit Server VM 1.8.0_152-b16 on Mac OS X 10.13.6
   Intel(R) Core(TM) i7-4558U CPU @ 2.80GHz
   long/nullable int/string to primitive:    Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
   ------------------------------------------------------------------------------------------------------------------------
   long/nullable int/string to primitive wholestage off             32             35           5          3,2         316,7       1,0X
   long/nullable int/string to primitive wholestage on             41             68          17          2,4         414,0       0,8X
   ```
   The improvements are particularly visible in the second case, ie. when only primitive types are used as inputs.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org