2017-06-06 208 views
0

最近,我正在学习Scala语言。今天我提出一个问题,那就是, 如何在需要太多时间终止一个函数。如何在Scala中花费太多时间来终止函数?

例如:

object HelloWorld { 
    def main(args: Array[String]) { 
    println("Hello, World") 
    // How to terminate the sum() function 
    // when the time that it takes greater than 2 second? 
    val t0 = System.nanoTime : Double 
    val total: BigInt = sum(1000000000) 
    val t1 = System.nanoTime : Double 
    println("Elapsed time " + (t1 - t0)/1000000.0 + " msecs") 

    println(total) 

    } 

    //Given that sum() is written by others and I cannot change it. 
    def sum(k: Int): BigInt = { 
    var total: BigInt = 0 
    for (i <- 1 to k) { 
     total += i 
    } 
    total 
    } 
} 

enter image description here

上面阶代码需要大约70。

回答

2

现在的计算会阻止您的主线程。那就是你的程序运行的线程。在你的计算完成之前,你没有控制权去执行那个线程上的任何东西。

您可以在单独运行Thread的计算中运行该计算,并在您认为计算时间过长时从主线程中删除Thread

注:当你是一个初学者斯卡拉:线程通常不是在斯卡拉的路要走,但在这种情况下,由斯卡拉(即Future S)提供的抽象不适合你低电平足够的”重新努力实现。请不要把低层次的Thread作为你每天应该做的事情。

+0

你能不能给我一个小的演示,因为我不不知道'Thread'。谢谢。我在工作中使用Maple和MATLAB大约5年。 – xyz

+0

您可以参考https://twitter.github.io/scala_school/concurrency.html#Thread。有关线程的简短介绍。 – markusthoemmes

+0

@markusthoemmes为什么不是'未来'的方式去这里?如果在“未来”区块中计算时间,则“未来”管理应该不会对时间测量产生任何影响(至少,这是我的理解)。 –

4

使用未来(S)!

val resultFuture : Future[ReturnType] = Future.apply { 
longComputation 
} 

val resultMaybeCut = Await.result(resultFuture, DurationOfChoice) 

对于记录,Await.result(awaitable:Awaitable [T],atMost:持续时间):

  • 抛出InterruptedException的如果在等待时
  • 当前线程被中断抛出TimeoutException异常如果后等待指定的时间awaitable仍未准备好
  • 如果atMost是Duration.Undefined,则抛出IllegalArgumentException异常

警告(谢谢@markusthoemmes):

这样做并不会打断未来的计算,它只是让您轻松超时! (这可能是也可能不是问题)。 如果我相信Kill or timeout a Future in Scala 2.10有没有超简单的方法来实际停止底层计算,所以你可能想参考其他解决方案张贴在这里!

+0

我不认为这实际上会停止计算。它退出程序(在这种情况下),但通常不会在将来停止计算。 – markusthoemmes

+0

这是一个很好的观点,取决于用例!我正在寻找相关的文件,请不要犹豫,如果你有任何联系:) – C4stor

1

线程不严格要求这一点,如果你有一个紧密的循环,只是想退出,如果条件没有一定的超时之前满足:

def sum(k: Int, timeoutMillis: Long): BigInt = { 
    val timeoutMillis = System.currentTimeMillis + timeoutMillis 
    var total: BigInt = 0 
    for (i <- 1 to k) { 
    total += i 
    if (timeoutMillis < System.currentTimeMillis) 
     throw new RuntimeException("Timed out") 
    } 
    total 
} 
+0

谢谢。我展示的代码只是我做的一个简单的例子。实际上,我想找到一种方法来处理由其他人编写的一般用户定义函数,否则我不能**改变它。 – xyz

+0

不够公平,我认为考虑你不需要跳转到线程来约束执行时间是非常重要的。 – SimonC

+0

对于*** Mathematica ***用户,通常我使用Alt +。 '放弃*** Mathematica ***核心的计算:) – xyz

相关问题