Ответ 1
RDD.isEmpty()
будет частью Spark 1.3.0.
Основываясь на предложениях этот почтовый поток apache, а затем некоторые комментарии к этому ответу, я сделал несколько небольших локальных экспериментов. Лучший способ - использовать take(1).length==0
.
def isEmpty[T](rdd : RDD[T]) = {
rdd.take(1).length == 0
}
Он должен работать в O(1)
, кроме случаев, когда RDD пуст, и в этом случае он является линейным по числу разделов.
Спасибо Джошу Розеном и Нику Чаммасу, чтобы указать на это.
Примечание. Это не удается, если RDD имеет тип RDD[Nothing]
, например. isEmpty(sc.parallelize(Seq()))
, но это, вероятно, не проблема в реальной жизни. isEmpty(sc.parallelize(Seq[Any]()))
отлично работает.
редактирует:
- Изменить 1: Добавлен метод
take(1)==0
, благодаря комментариям.
Мое первоначальное предложение: Используйте mapPartitions
.
def isEmpty[T](rdd : RDD[T]) = {
rdd.mapPartitions(it => Iterator(!it.hasNext)).reduce(_&&_)
}
Он должен масштабироваться в количестве разделов и не так чист, как take(1)
. Однако он устойчив к RDD типа RDD[Nothing]
.
Эксперименты:
Я использовал этот код для таймингов.
def time(n : Long, f : (RDD[Long]) => Boolean): Unit = {
val start = System.currentTimeMillis()
val rdd = sc.parallelize(1L to n, numSlices = 100)
val result = f(rdd)
printf("Time: " + (System.currentTimeMillis() - start) + " Result: " + result)
}
time(1000000000L, rdd => rdd.take(1).length == 0L)
time(1000000000L, rdd => rdd.mapPartitions(it => Iterator(!it.hasNext)).reduce(_&&_))
time(1000000000L, rdd => rdd.count() == 0L)
time(1000000000L, rdd => rdd.takeSample(true, 1).isEmpty)
time(1000000000L, rdd => rdd.fold(0)(_ + _) == 0L)
time(1L, rdd => rdd.take(1).length == 0L)
time(1L, rdd => rdd.mapPartitions(it => Iterator(!it.hasNext)).reduce(_&&_))
time(1L, rdd => rdd.count() == 0L)
time(1L, rdd => rdd.takeSample(true, 1).isEmpty)
time(1L, rdd => rdd.fold(0)(_ + _) == 0L)
time(0L, rdd => rdd.take(1).length == 0L)
time(0L, rdd => rdd.mapPartitions(it => Iterator(!it.hasNext)).reduce(_&&_))
time(0L, rdd => rdd.count() == 0L)
time(0L, rdd => rdd.takeSample(true, 1).isEmpty)
time(0L, rdd => rdd.fold(0)(_ + _) == 0L)
На моей локальной машине с 3 рабочими ядрами я получил эти результаты
Time: 21 Result: false
Time: 75 Result: false
Time: 8664 Result: false
Time: 18266 Result: false
Time: 23836 Result: false
Time: 113 Result: false
Time: 101 Result: false
Time: 68 Result: false
Time: 221 Result: false
Time: 46 Result: false
Time: 79 Result: true
Time: 93 Result: true
Time: 79 Result: true
Time: 100 Result: true
Time: 64 Result: true