我正在写一个玩游戏的ai(aichallenge.org - Ants),它需要大量更新,并引用数据结构.我已经尝试了数组和地图,但基本问题似乎是每次更新都会创建一个新值,这会让它变慢.如果您花费超过一秒钟来进行移动,游戏会引导您,因此应用程序将被视为"硬实时".是否有可能在Haskell中具有可变数据结构的性能,或者我应该学习Python,还是在OCaml中重写我的代码?
我完全改写了蚂蚁"初学者包".从阵列更改为地图,因为我的测试显示地图更新速度更快.
我运行了地图版本并进行了分析,结果显示仅有20%的时间是由地图更新单独进行的.
这是一个简单的演示,说明阵列更新的速度有多慢.
slow_array =
let arr = listArray (0,9999) (repeat 0)
upd i ar = ar // [(i,i)]
in foldr upd arr [0..9999]
Run Code Online (Sandbox Code Playgroud)
现在评估slow_array!9999需要将近10秒!虽然一次应用所有更新会更快,但该示例模拟了每回合必须更新阵列的真正问题,并且最好每次在计划下一轮时选择移动.
感谢nponeccop和Tener参考矢量模块.以下代码等同于我的原始示例,但运行时间为0.06秒而不是10秒.
import qualified Data.Vector.Unboxed.Mutable as V
fast_vector :: IO (V.IOVector Int)
fast_vector = do
vec <- V.new 10000
V.set vec 0
mapM_ (\i -> V.write vec i i) [0..9999]
return vec
fv_read :: IO Int
fv_read = do
v <- fast_vector
V.read v 9999
Run Code Online (Sandbox Code Playgroud)
现在,将其纳入我的蚂蚁代码......
我想要一个方法来更新IEnumerable的某些条目.我发现在条目中做一个foreach并更新值失败,因为我在克隆集合的后台.这是因为我的IEnumerable得到了一些LINQ-> SQL查询的支持.
通过更改方法以获取List我已经更改了此行为,Lists总是可变的,因此该方法更改列表中的实际对象.而不是要求传递List是否有可以使用的Mutable接口?
// Will not behave as consistently for all IEnumerables
public void UpdateYesterday (IEnumerable<Job> jobs) {
foreach (var job in jobs.Where(x => x.date == Yesterday)) {
job.done = true;
}
}
...
public class Job {
...
public DateTime Date { get; set; }
}
Run Code Online (Sandbox Code Playgroud) 我希望重新定义或更新模块中的一些绑定,然后由注入器使用.我意识到模块是不可变的,一旦绑定被吸入并注入其定义,就不能为所有实际目的而改变.
我想添加/更改/删除绑定,同时保持单身人士已经生活在注射器中.更改是一个简单的案例,因为可以通过使用提供程序来实现此效果.但是,动态添加或删除密钥(绑定定义)有点棘手.
任何想法,如果这应该或可以实际完成.
我认为最好的方法是每次添加/删除绑定时都重新创建一个注入器,将定义从原始复制到新的,任何现有的单例都将由toInstance重新定义,而不是实现类型等.
我读了Cocoa和Objective C:Up and Running,-copy它将始终返回一个不可变对象并-mutableCopy始终返回一个可变对象:
重要的是要知道调用
-copy一个可变对象会返回一个不可变的版本.如果要复制可变对象并在新版本中保持可变性,则必须调用-mutableCopy原始对象.但这很有用,因为如果你想"冻结"一个可变对象,你可以调用-copy它.
所以我有这样的事情:
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
NSLog( @"%@", [req className] ); // NSMutableURLRequest
NSLog( @"%@", [[req copy] className] ); // NSMutableURLRequest
NSLog( @"%@", [[req mutableCopy] className] ); // NSMutableURLRequest
Run Code Online (Sandbox Code Playgroud)
根据之前的回答:
你不能依赖复制的结果是可变的!复制一个
NSMutableArray可以返回一个NSMutableArray,因为那是原始类,但复制任意NSArray实例都不会.
这似乎有点孤立NSURLRequest,因为NSArray按预期行事:
NSArray *arr = [[NSMutableArray alloc] init];
NSLog( @"%@", [arr className] ); // __NSArrayM
NSLog( @"%@", [[arr copy] className] …Run Code Online (Sandbox Code Playgroud) 我想知道mutable如何影响容器(map,vector,list,...).另外,我还要记住什么?
假设我正在创建一个表示分数的Objective-C类,并且想要创建不可变和可变的版本.
遵循Foundation框架中的模式,您可能希望fractionByAddingFraction:在不可变版本和addFraction:可变版本中看到该方法.
我遇到的悖论是如何在两个类之间只包含一次分数加法逻辑.似乎不可变fractionByAddingFraction:方法需要知道(并利用)可变addFraction:方法以避免代码重复,并且在可执行类的实现中包含可变方法意味着可以想象它们可以在不可变对象上调用,这打败了这一点.
非常感谢一个简短的解释(或者更好的是,这个简化示例的延续)!
使用Chris Smith的Programming F#3.0中的一个例子:
let invalidUseOfMutable() =
let mutable x = 0
let incrementX() = x <- x + 1
incrementX()
x;;
Run Code Online (Sandbox Code Playgroud)
这按预期失败:
错误FS0407:可变变量'x'以无效方式使用.闭包不能捕获可变变量.
现在将函数体剪切并粘贴到FSharp Interactive中:
let mutable x = 0
let incrementX() = x <- x + 1
incrementX()
x;;
Run Code Online (Sandbox Code Playgroud)
它的工作原理!
val it:int = 1
为什么?
这是我写的描述我的问题的伪代码: -
func(s):
#returns a value of s
x = a list of strings
print func(x)
print x #these two should give the SAME output
Run Code Online (Sandbox Code Playgroud)
当我最后打印x的值时,我希望它是func(x)返回的值.我只能通过编辑功能(并且不设置x = func(x))来执行此类操作
我有一个列表,它是我班上的私人成员。我使用 getter 和 setter 来获取和设置值。SOnar 引发错误 - 不应直接存储或返回可变成员。
例如:ABC 和 DEF 是两个类。
class ABC{
private List<DEF> defList;
public List<DEF> getDefList() { return defList; }
public void setDefList(List<DEF> defList) { this.defList = defList; }
Run Code Online (Sandbox Code Playgroud)
经过大量的谷歌搜索和搜索,我了解到可以按如下方式更改 getter:
public List<DEF> getDefList() { return new ArrayList<>(defList); }
Run Code Online (Sandbox Code Playgroud)
当我尝试类似地使用 setter 时,
public void setDefList(List<DEF> defList) { this.defList.addAll(defList); }
Run Code Online (Sandbox Code Playgroud)
然后变量开始显示
'private field 'defList' is never assigned.
Run Code Online (Sandbox Code Playgroud)
我可以知道当它是一个列表时的正确方法吗(另一个类的列表)
注意:Prasad Karunagoda 和 Leo Aso 的答案都有效。我不能将两者都标记为已接受的答案。所以在这里做个笔记
来自 Wolfram Mathematica,我喜欢这样的想法,即每当我将变量传递给函数时,我实际上是在创建该变量的副本。另一方面,我了解到在 Julia 中有可变和不可变类型的概念,前者通过引用传递,后者通过值传递。有人可以向我解释这种区别的优势吗?为什么数组是通过引用传递的?我天真地认为这是一个不好的方面,因为它会产生副作用并破坏编写纯函数代码的可能性。我的推理哪里错了?有没有办法使数组不可变,这样当它传递给函数时,它实际上是按值传递的?
这里是代码示例
#x is an in INT and so is immutable: it is passed by value
x = 10
function change_value(x)
x = 17
end
change_value(x)
println(x)
#arrays are mutable: they are passed by reference
arr = [1, 2, 3]
function change_array!(A)
A[1] = 20
end
change_array!(arr)
println(arr)
Run Code Online (Sandbox Code Playgroud)
这确实修改了数组 arr
mutable ×10
cocoa ×2
immutability ×2
objective-c ×2
arraylist ×1
arrays ×1
c# ×1
c++ ×1
closures ×1
f# ×1
function ×1
guice ×1
haskell ×1
ienumerable ×1
java ×1
julia ×1
performance ×1
profiling ×1
python ×1
sonarqube ×1