2017-11-13 15 views
0

spap(EMRで実行中)のUDFは、uaparserライブラリ(uap-scala)を使用してユーザエージェントからデバイスを解析するscalaで書かれています。小さなセットで作業する場合、それはうまく動作します(5000行)が、大きなセット(2M)で動作すると非常に遅くなります。私は労働者SparkのUDFは非常に遅いです

  1. がどのように私はこれを確立することができUDFドライバで実行されていることを信じていない作るもの、 は私が一覧表示するデータフレームを収集し、ドライバーにそれをループ試みたが、それも非常に遅かったですか?誰か別の理論を持っていますか?
  2. これが当てはまる場合、なぜこれが起こりますか?

これはUDFコードです:

def calcDevice(userAgent: String): String = { 

val userAgentVal = Option(userAgent).getOrElse("") 
Parser.get.parse(userAgentVal).device.family 
} 

val calcDeviceValUDF: UserDefinedFunction = udf(calcDevice _) 

用法:

.withColumn("agentDevice", udfDefinitions.calcDeviceValUDF($"userAgent")) 

おかげ ニール

+0

いくつかの値が異なる行によって共有されることがありますか? –

+0

はい、ユーザーエージェントが繰り返し実行されますが、リストはあまり小さくありません –

+0

構文解析にはコストがかかるかもしれません - キャッシュを使用した場合のヒット%はどれですか? –

答えて

0

質問から欠落しているParser.get.parseを考えると、それだけでudfを判断することができます部。

パフォーマンスを得るために、あなたはOptionを削除することができます

def calcDevice(userAgent: String): String = { 
    val userAgentVal = if(userAgent == null) "" else userAgent 
    Parser.get.parse(userAgentVal).device.family 
} 
1

問題は、UDF itelf内ビルダーをインスタンス化していました。解決策は、udfの外側にオブジェクトを作成し、それを行レベルで使用することです:

val userAgentAnalyzerUAParser = Parser.get 

def calcDevice(userAgent: String): String = { 

val userAgentVal = Option(userAgent).getOrElse("") 
userAgentAnalyzerUAParser.parse(userAgentVal).device.family 
} 

val calcDeviceValUDF: UserDefinedFunction = udf(calcDevice _) 
関連する問題