我的游戏有一个像这样的声音对象:
object Sounds {
SoundFactory.setAssetBasePath("mfx/")
val EXPLOSION_0 = ESound("explosion1.ogg")
val EXPLOSION_1 = ESound("explosion2.ogg")
val EXPLOSION_2 = ESound("explosion3.ogg")
val IMPACT_0 = ESound("impact1.ogg", 0.4f)
val IMPACT_1 = ESound("impact2.ogg", 0.4f)
val IMPACT_2 = ESound("impact3.ogg", 0.4f)
val BONUS = ESound("bonus.ogg", 0.7f)
// -- snip --
def load() {
println("Sounds loaded")
}
case class ESound(sound_file: String, volume: Float = 1) {
private val sound = SoundFactory.createSoundFromAsset(AndEngine.engine.getSoundManager, AndEngine.activity.get, sound_file)
sound.setVolume(volume)
sound.setLoopCount(0)
def play() { sound.play() }
}
}
Run Code Online (Sandbox Code Playgroud)
为简洁起见,我删除了许多方法等.但基本的想法是Scala懒惰地load()将对象初始化,所以我第一次在这个对象上调用一些方法()它会被初始化.这将在例如纹理加载等之后完成.
但是使用上面的代码,我第一次按下游戏中的某个菜单按钮时,我得到一个长时间的停顿,因为它只会加载所有这些声音(由SoundFactory.createSound...构造函数中的引起).
现在,如果我将load …
不确定在构造延迟序列时使用flatten时我观察到的行为是什么.
查看clojure.core中的源代码,我可以看到flatten函数调用filter,因此应该返回一个惰性序列 - 我想.但是下面的代码片段给了我一个stackoverflow错误.在使用对concat的调用替换对flatten的调用的代码段中,它工作得很好
(defn l-f [c]
(if (nil? c) []
(lazy-seq (flatten (cons [[ :h :j] :a :B] (l-f (rest c)))))))
(take 10 (l-f (repeat 2))) is how I invoke it.
Run Code Online (Sandbox Code Playgroud)
这是一个相当人为的例子.我也知道flatten和concat会给我一些嵌套级别不同的序列.
我试图找出为什么flatten似乎打破了懒惰,即使我对clojure.core中的代码的(有限的)理解建议不然.
在这段代码中:
fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Just False))
fromMaybe <$> (print "A" >> return True) <*> (print "B" >> (return $ Nothing))
Run Code Online (Sandbox Code Playgroud)
我预计,由于懒惰,"A"或"B"将被打印,这取决于我是否提供Just something或者Nothing两者都打印,无论如何.有人可以解释一下这里到底发生了什么?和b)我怎样才能达到我想要的效果?
你可以告诉我在执行以下代码时内存中发生了什么:
情况1:
public static void Execute()
{
foreach(var text in DownloadTexts())
{
Console.WriteLine(text);
}
}
public static IEnumerable<string> DownloadTexts()
{
foreach(var url in _urls)
{
using (var webClient = new WebClient())
{
yield return webClient.DownloadText(url);
}
}
}
Run Code Online (Sandbox Code Playgroud)
让我们假设在第一次迭代后我得到html1.
什么时候从内存中清除html1?
谢谢
**编辑**
案例2:
public static void Execute()
{
var values = DownloadTexts();
foreach(var text in values)
{
Console.WriteLine(text);
}
}
public static IEnumerable<string> DownloadTexts()
{
foreach(var url in _urls)
{
using (var webClient = new WebClient())
{ …Run Code Online (Sandbox Code Playgroud) 我有一个DAO对象,我将其定义为案例类.
case class StudentDAO(id: Int) {
def getGPA: Double = // Expensive database lookup goes here
def getRank: Int = // Another expensive database operation and computation goes here
def getScoreCard: File = // Expensive file lookup goes here
}
Run Code Online (Sandbox Code Playgroud)
我自然会制作getGPA和getRank而getScoreCard def不是vals因为我不希望它们在被使用之前被计算出来.
如果我将这些方法标记为lazy vals而不是defs,会对性能产生什么影响?我想让它们成为lazy vals 的原因是:我不想每次为id为"i"的学生重新计算等级.
我希望这不会被标记为重复,因为有几个问题如下,主要是差异:
Scala中的`def` vs`val` vs`lazy val`评估
这个问题主要是针对朝费用(CPU与内存之间的权衡)在作出method一个lazy val昂贵的操作,什么会建议一个比其他?为什么?
编辑:感谢您对@ om-nom-nom的评论.我应该更清楚我正在寻找什么.
我在这里读到:
我正在通过以下方式在Swift中尝试内存管理.
class Person {
let name: String
//var block: (() -> Void)?
init(name: String) {
self.name = name
}
// Declare variable clone, using self inside.
private lazy var clone: String = {
return self.name
}()
deinit {
print("Destroying \(name)")
}
func doSomething() {
print("Doing something for \(name)")
}
}
var p2: Person? = Person(name: "p2")
print(p2!.clone)
p2 = nil
Run Code Online (Sandbox Code Playgroud)
如你所见,我self在声明一个懒惰的var时使用内部,我认为它仍然可以,因为当p2变为nil时,我可以看到该deinit方法被调用.
但是,如果我做了如下更改
// This is a closure
private lazy var clone: () -> String = { …Run Code Online (Sandbox Code Playgroud) 我有以下课程:
@Repository
class A {
public void method1() {
...
}
}
@Component
class B implements C {
@Autowired
@Lazy
private A a;
public void method2() {
a.method1();
}
}
@Component
class D {
@Autowired
private List<C> c;
@PostConstruct
public void method3() {
// iterate on list c and call method2()
}
}
Run Code Online (Sandbox Code Playgroud)
让我们假设Spring将bean初始化如下:
1.创建第一个bean B. 当创建bean B时,a由于@Lazy注释,将不会初始化字段.
2.创建下一个bean D. 然后method3()将被标记为执行@PostConstruct,但Spring尚未触及bean A. 因此,当调用a.method1()时,Spring会创建bean A并将其注入字段中a还是会抛出NullPointerException?
我想出了原始输入问题的以下代码,正如SO Haskell中读到的原始键盘输入所讨论的那样.不幸的是,当我去ghci,运行getAllInput并点击右箭头键时,它永远不会返回.除非我很快就杀了它,它似乎占用了我所有的内存,以便其他应用程序停止响应,我必须重新启动操作系统.在活动监视器中,我可以看到ghc进程的内存快速进入千兆字节.
(1)我认为问题出在递归调用中go,通过hReady之前的调用来懒惰地评估getChar; 这意味着hReady保持返回true并且堆栈永远增长.这看起来有道理吗?
(2)我习惯于很快会导致堆栈溢出异常的语言,所以它不会阻止我工作.有没有一般的方法来防止这种大规模的内存泄漏?也许以内存使用的硬限制开始ghci?
import System.IO
-- For example, should get "\ESC[C" from the user hitting the right arrow key.
getAllInput :: IO [Char]
getAllInput =
let
go :: IO [Char] -> IO [Char]
go chars = do
more <- hReady stdin
if more then go (added chars getChar) else chars
added :: IO [Char] -> IO Char -> IO [Char]
added chars char = do
chars1 …Run Code Online (Sandbox Code Playgroud) 考虑将列表连接实现为左侧折叠,即foldl (++) [].在惰性求值语言中,例如Haskell,这种实现的复杂性是什么?我理解,在严格的语言中,表现是元素总数的二次方,但是当涉及懒惰时会发生什么?
我试图用手工评估表达式([1,2,3] ++ [4,5,6]) ++ [7,8,9](对应于foldl (++) [] [[1,2,3], [4,5,6], [7,8,9]]),似乎我们只遍历每个元素一次,但我不确定我的推理是否正确:
([1,2,3] ++ [4,5,6]) ++ [7,8,9]
= { rewrite expression in prefix notation }
(++) ((++) [1,2,3] [4,5,6]) [7,8,9]
= { the first (++) operation needs to pattern match on its first argument; so it evaluates the first argument, which pattern matches on [1,2,3] }
(++) (case [1,2,3] of {[] -> [4,5,6]; x:xs' -> x:(++) xs' [4,5,6]}) [7,8,9]
= { x = …Run Code Online (Sandbox Code Playgroud) 您将如何在不使用for循环的情况下重写它?
const a = [2, 5, 78, 4];
const expensiveFunction = n => 2 * n;
let result;
// Find the first number
for (let i = 0; i < a.length; i++) {
const r = expensiveFunction(a[i]);
if (r > 100) {
result = r;
break;
}
}
console.log(result);
Run Code Online (Sandbox Code Playgroud)
我的天真做法:
const result = a.map(expensiveFunction).find(x => x > 100);
console.log(result);
Run Code Online (Sandbox Code Playgroud)
但这expensiveFunction涉及所有要素,我想避免。在上述情况下,我们应避免运行expensiveFunction(4)。
有些语言具有find_map(例如Rust),我没在lodash或下划线中找到它。
lazy-evaluation ×10
haskell ×3
memory-leaks ×2
scala ×2
annotations ×1
c# ×1
clojure ×1
flatten ×1
function ×1
io ×1
java ×1
javascript ×1
list ×1
memory ×1
performance ×1
spring ×1
swift ×1
yield-return ×1