我有一种生成UUID的方法和代码如下:
functions
我将其称为如下:
def generate(number : Int): List[String] = {
List.fill(number)(Generators.randomBasedGenerator().generate().toString.replaceAll("-",""))
}
但是为了运行上面的for(i <-0 to 100) {
val a = generate(1000000)
println(a)
}
循环,执行需要大约8-9分钟,还有其他方法可以最小化执行时间吗?
注意:为了便于理解,我添加了for
循环,但在实际情况下,for
方法会同时从其他请求调用数千次。
答案 0 :(得分:2)
问题是List
。使用1,000,000个生成和处理的元素填充List
将需要时间(和内存),因为必须实现这些元素中的每一个。
如果您不需要实现它们,则可以立即生成无限数量的已处理UUID字符串,直到实际需要它们为止。
def genUUID :Stream[String] = Stream.continually {
Generators.randomBasedGenerator().generate().toString.filterNot(_ == '-')
}
val next5 = genUUID.take(5) //only the 1st (head) is materialized
next5.length //now all 5 are materialized
您可以使用Stream
或Iterator
进行无限收集,无论哪种情况对您的工作流程最有利(或最不烦人)。
答案 1 :(得分:1)
您可以使用scala的并行集合来分割多个核心/线程上的负载。
您还可以避免每次都创建新的生成器:
class Generator {
val gen = Generators.randomBasedGenerator()
def generate(number : Int): List[String] = {
List.fill(number)(gen.generate().toString.replaceAll("-",""))
}
}
答案 2 :(得分:1)
基本上你没有使用最快的实现。将Random传递给构造函数Generators.randomBasedGenerator(new Random(System.currentTimeMillis()))
时应该使用那个。我做了下一件事:
依赖关系:"com.fasterxml.uuid" % "java-uuid-generator" % "3.1.5"
结果:
Generators.randomBasedGenerator(). Per iteration: 1579.6 ms
Generators.randomBasedGenerator() with passing Random Per iteration: 59.2 ms
代码:
import java.util.{Random, UUID}
import com.fasterxml.uuid.impl.RandomBasedGenerator
import com.fasterxml.uuid.{Generators, NoArgGenerator}
import org.scalatest.{FunSuiteLike, Matchers}
import scala.concurrent.duration.Deadline
class GeneratorTest extends FunSuiteLike
with Matchers {
val nTimes = 10
// Let use Array instead of List - Array is faster!
// and use pure UUID generators
def generate(uuidGen: NoArgGenerator, number: Int): Seq[UUID] = {
Array.fill(number)(uuidGen.generate())
}
test("Generators.randomBasedGenerator() without passed Random (secure one)") {
// Slow generator
val uuidGen = Generators.randomBasedGenerator()
// Warm up JVM
benchGeneration(uuidGen, 3)
val startTime = Deadline.now
benchGeneration(uuidGen, nTimes)
val endTime = Deadline.now
val perItermTimeMs = (endTime - startTime).toMillis / nTimes.toDouble
println(s"Generators.randomBasedGenerator(). Per iteration: $perItermTimeMs ms")
}
test("Generators.randomBasedGenerator() with passing Random (not secure)") {
// Fast generator
val uuidGen = Generators.randomBasedGenerator(new Random(System.currentTimeMillis()))
// Warm up JVM
benchGeneration(uuidGen, 3)
val startTime = Deadline.now
benchGeneration(uuidGen, nTimes)
val endTime = Deadline.now
val perItermTimeMs = (endTime - startTime).toMillis / nTimes.toDouble
println(s"Generators.randomBasedGenerator() with passing Random Per iteration: $perItermTimeMs ms")
}
private def benchGeneration(uuidGen: RandomBasedGenerator, nTimes: Int) = {
var r: Long = 0
for (i <- 1 to nTimes) {
val a = generate(uuidGen, 1000000)
r += a.length
}
println(r)
}
}