我的引擎正在 X 上执行 1,000,000 次模拟交易。在每次模拟期间,对于每笔交易,可以验证特定条件。在本例中,我将值(double)存储到一个数组中。每笔交易都有自己的值列表(即这些值独立于一笔交易与另一笔交易)。
在所有模拟结束时,对于每笔交易,我都在他的 List<Double> 上运行一个算法得到一些输出。不幸的是,该算法需要这些值的完整列表,因此,我无法修改我的算法以“即时”计算输出,即在模拟期间。
在“正常”条件下(即 X 较低,并且条件验证的时间少于 10%),计算正确结束,即使这可能会得到增强。
当我有很多交易(例如 X = 30 )并且我几乎所有的模拟都验证了我的特定条件(比如说 90% 的模拟)时,我的问题就出现了。所以只是为了存储值,我需要大约 900,000 * 30 * 64bits内存(约 216Mb)。我 future 的要求之一是能够运行 5,000,000 次模拟...
所以我无法继续使用当前存储值的方式。目前,我使用了 Map<String, List<Double>> 的“简单”结构,其中键是元素的 ID,List<Double>值列表。
所以我的问题是如何增强应用程序的这个特定部分以减少模拟期间的内存使用量?
还有一个重要的注意事项是,对于最终计算,我的 List<Double> (或我将使用的任何结构)必须订购。因此,如果我上一个问题的解决方案还提供了一种结构来对新插入的元素进行排序(例如 SortedMap ),那就太棒了!
我正在使用 Java 1.6。
编辑 1
我的引擎确实在执行一些财务计算,在我的例子中,所有交易都是相关的。这意味着我无法对第一笔交易运行我的计算,获取输出,清理 List<Double> ,然后转到第二笔交易,依此类推。
当然,作为临时解决方案,我们会增加分配给引擎的内存,但这不是我期望的解决方案;)
编辑2
关于算法本身。我不能在这里给出确切的算法,但这里有一些提示:
我们必须处理一个已排序的 List<Double> .然后我将计算一个索引(根据给定参数和 List 本身的大小计算)。然后,我终于返回了 index-th此列表的值。
public static double algo(double input, List<Double> sortedList) {
if (someSpecificCases) {
return 0;
}
// Calculate the index value, using input and also size of the sortedList...
double index = ...;
// Specific case where I return the first item of my list.
if (index == 1) {
return sortedList.get(0);
}
// Specific case where I return the last item of my list.
if (index == sortedList.size()) {
return sortedList.get(sortedList.size() - 1);
}
// Here, I need the index-th value of my list...
double val = sortedList.get((int) index);
double finalValue = someBasicCalculations(val);
return finalValue;
}
我希望现在有这样的信息会有所帮助...
编辑3
目前,我不会考虑任何硬件修改(这里太长太复杂:( )。增加内存的解决方案会完成,但这只是一个快速修复。
我在想一个使用临时文件的解决方案:直到某个阈值(例如 100,000),我的 List<Double>在内存中存储新值。当 List<Double> 的大小达到此阈值,我将此列表附加到临时文件中(每笔交易一个文件)。
类似的东西:
public void addNewValue(double v) {
if (list.size() == 100000) {
appendListInFile();
list.clear();
}
list.add(v);
}
在整个计算结束时,对于每笔交易,我将重建完整的 List<Double>从我在内存中以及在临时文件中的内容。然后,我运行我的算法。我清理这笔交易的值(value),然后转到第二笔交易(我现在可以这样做,因为所有模拟现在都已完成)。
您如何看待这样的解决方案?你觉得可以接受吗?
当然我会浪费一些时间在外部文件中读取和写入我的值,但我认为这是可以接受的,不是吗?
最佳答案
您的问题是算法问题,您正在寻找“强度降低”优化。
不幸的是,您在问题描述中过于害羞并说“不幸的是,该算法需要这些值的完整列表...”,这是可疑的。模拟运行已经通过了一个谓词,该谓词本身会告诉您有关通过筛子的集合的一些信息。
我希望符合条件的数据具有 low information content因此可以进行大量压缩。
如果没有进一步的信息,我们真的无法为您提供更多帮助。
关于java - 如何在计算期间存储数百万个 Double?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3934660/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/