我有一个生成UUID和代码的方法,如下所示:
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)
}但是对于运行上面的for循环,执行几乎需要8-9分钟,还有其他方法来最小化执行时间吗?
注意:为了理解我添加了for循环,这里的,但是在实际情况下,generate方法将从其他请求同时调用上千次。
发布于 2018-04-10 06:41:21
基本上,您使用的不是最快的实现。当您将随机传递给构造函数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)
}
}发布于 2018-04-09 19:41:01
问题是List。用1,000,000个生成和处理的元素填充List需要时间(和内存),因为这些元素中的每一个都必须物化。
如果您不必在实际需要之前实现UUID字符串,则可以立即生成无限数量的处理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,无论您认为对工作流程最有利(或最不烦人)。
发布于 2018-04-09 18:48:40
您可以使用scala的并行集合在多个核心/线程上拆分负载。
您还可以避免每次创建一个新生成器:
class Generator {
val gen = Generators.randomBasedGenerator()
def generate(number : Int): List[String] = {
List.fill(number)(gen.generate().toString.replaceAll("-",""))
}
}https://stackoverflow.com/questions/49738619
复制相似问题