在编写用于OpenGL库的Matrix类时,我遇到了是否使用Java数组或缓冲区策略来存储数据的问题(JOGL为Matrix操作提供了直接缓冲区复制).为了分析这一点,我编写了一个小型性能测试程序,它比较了Arrays与Buffers vs direct Buffers的循环和批量操作的相对速度.
我想在这里与你分享我的成果(因为我觉得它们很有趣).请随时评论和/或指出任何错误.
可以在pastebin.com/is7UaiMV上查看代码.
循环读取数组实现为A [i] = B [i],否则JIT优化器将完全删除该代码.实际var = A [i]似乎几乎相同.
在数组大小为10,000的示例结果中,JIT优化器很可能已使用类似System.arraycopy的实现替换了循环数组访问.
没有批量获取缓冲区 - >缓冲区,因为Java将A.get(B)实现为B.put(A),因此结果与批量放置结果相同.
在几乎所有情况下,强烈建议使用Java内部数组.不仅提高/获取速度大大加快,JIT还能够对最终代码执行更好的优化.
只有在以下两种情况适用时才应使用缓冲区:
请注意,后备缓冲区具有Java数组,用于补偿缓冲区的内容.建议在此后台缓冲区上执行操作,而不是循环put/get.
只有在担心内存使用情况且永远不会访问基础数据时,才应使用直接缓冲区.它们比非直接缓冲区稍慢,如果访问基础数据则要慢得多,但使用的内存较少.此外,在使用直接缓冲区时,将非字节数据(如float-arrays)转换为字节时会产生额外的开销.
有关详细信息,请参阅此处
注意:百分比仅为便于阅读而没有实际意义.
-- Array tests: -----------------------------------------
Loop-write array: 87.29 ms 11,52%
Arrays.fill: 64.51 ms 8,51%
Loop-read array: 42.11 ms 5,56%
System.arraycopy: 47.25 ms 6,23%
-- …
Run Code Online (Sandbox Code Playgroud) 我在多年前由C程序员实现的工作中偶然发现了一个旧的Java代码,我们不禁开始讨论代码 - 即使它编译和工作 - 实际上是有效的Java代码.
final Object o = Boolean.TRUE;
boolean b = (boolean) o;
Run Code Online (Sandbox Code Playgroud)
这基本上是有问题的代码.正如你所看到的,从对象到原始布尔值有一个不太好的演员,这应该是不可能的,但是由于一些隐含的拳击魔术而恰好起作用.
如果我做以下事情
final Object o = Boolean.TRUE;
if (o instanceof Boolean) {
b = (boolean) o;
}
Run Code Online (Sandbox Code Playgroud)
我甚至在o被投射到b的行上发出警告,说"Cast与给定的instanceof不兼容".这显然是正确的,但由于隐式拳击仍然有效.
现在问题是:Java规范实际上是否允许转换,因此应该适用于未来的JVM版本?或者它恰好在当前版本中工作,可能不再适用于未来的JVM更新?
经过长时间的摆弄,直到我在Netbeans 8.2中使用Spring Boot 1.4.3进行了适当的调试设置,我想我将其调查结果记录为其他人的Q&A.
问题是Netbeans的默认配置无法在调试模式下正确启动Spring,当您搜索Internet时,您只能在Spring文档中找到不起作用的过时信息.
如果您知道如何解决方案很简单.请在下面找到正确的设置说明.
使用ClassLoader.getResourceAsStream(...)从可执行JAR文件本身读取文件对我来说是一个众所周知的概念,但我如何使用Java NIO做同样的事情呢?
目标是具有如下功能:
static String readFullyFromJar(String filename) {
final Path path = Paths.get(Main.class.getResource(fileName).toURI());
final byte[] bytes = Files.readAllBytes(path);
return new String(bytes, CHARSET_ASCII);
}
Run Code Online (Sandbox Code Playgroud)
虽然这在IDE中运行良好,但我得到了一个
java.nio.file.FileSystemNotFoundException
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171))
Run Code Online (Sandbox Code Playgroud)
当我尝试使用真正的JAR时,即使目标文件位于正确的位置.
我目前有一个Map<String, String>
包含表单中的值key = value
,我想将它们“扩展”为一个真实的对象。
是否可以使用 MapStruct 自动执行此操作,我将如何执行此操作?
澄清一下:我手工编写的代码如下所示:
public MyEntity mapToEntity(final Map<String, String> parameters) {
final MyEntity result = new MyEntity();
result.setNote(parameters.get("note"));
result.setDate(convertStringToDate(parameters.get("date")));
result.setCustomer(mapIdToCustomer(parameters.get("customerId")));
// ...
return result;
}
Run Code Online (Sandbox Code Playgroud) 由于我们的数据库模型中的一些怪癖,我面临着一个可以选择链接到自身的表。我想编写一个查询,以返回原始行或(如果存在)链接行的方式选择每一行。
SELECT
COALESCE(r2.*, r1.*)
FROM mytable r1
LEFT JOIN mytable r2
ON r1.sub_id = r2.id
Run Code Online (Sandbox Code Playgroud)
虽然此方法有效,但所有数据都作为元组而不是实际的表列返回到一列“COALESCE”中。
如何解压这些元组以获取实际的表行或“修复”查询以完全避免它?
在我当前在JBoss服务器上运行的项目中,需要添加所有依赖项,provided
就像它们由JBoss提供一样。但是对于我的单元测试,我确实需要那些没有JBoss服务器提供它们(iE javaee-api)的库,但是我不能两次添加具有不同作用域的相同依赖项。
如何provided
为运行时添加依赖关系,但test
对于单元测试如何添加依赖关系?
题
由于 Fork-Join 似乎是当前的炒作并在许多答案中被推荐,我想:为什么不对它的实际速度进行一些研究?
为了衡量这一点,我编写了一个小程序(见下面的代码),它做一些数字相加,并用各种参数将其分叉出来,包括线程数、分叉深度和分叉传播,然后测量执行时间,尤其是实际计算所花费的时间与分叉所花费的时间。
摘要答案
虽然实施得很好,但 ForkJoin 是并行化任务的一种极其低效的方式,因为每个 fork 的成本非常高。一个简单的问题优化实现可以轻松地存档 99% 的线程执行时间(这超过了使用 Fork-Join 测量的所有内容),因此这样的实现总是比 Fork-Join 实现更快。此外,如果每个 fork 的实际任务很小,则 Fork-Join 实现可能比单线程线性实现慢得多。
所以 Fork-Join 更重要的是它是否有助于您的代码架构,因为它与其他实现相比没有任何性能优势。因此,只有在以下情况下才应使用 Fork-Join:
性能并不重要,任务经常需要等待其他任务的结果才能继续。所以基本上如果 Fork-Join 结构大大简化了一个简单的实现的任务。
实际任务需要大大超过分叉的成本,因此损失可以忽略不计。在我的测试中,添加 2 个值的循环必须在每个 fork 循环至少 10000 次才能获得合理的性能。
编辑:请参阅此处了解我被指出的更深入的分析。
测试设置
在我的程序中,我有一个 RecursiveTask 计算给定 N 的斐波那契数列,这将实际计算减少到 3 个分配和 1 个加法。对于任何给定的 CPU,这应该是一项次要任务。
在测试中,我改变了线程数量、每个任务的分叉数量和斐波那契循环的长度。此外,我对 async 参数进行了一些测试,但将其设置为 false 只会显示计算时间的轻微减少,因此我跳过了它。传播参数(fork per fork)也大部分被跳过,因为结果没有显着差异。
一般来说,计算时间是非常稳定的,实际花费在任务上的时间百分比通常变化不到 1%,因此每个测试集已经在其他空闲系统上运行了大约 5 次(如果数字不稳定,则更多)具有 4 个核心(+4 个超核心),然后选择了中值执行时间。
已通过各种测试变量验证了正确执行,特别是已验证使用的实际线程数与最初给定的并行度参数绝无不同。
详细测试结果
在哪里:
Time total
是从主线程的角度来看整个计算所花费的总时间。Time task
是在所有分叉组合中实际计算斐波那契数列所花费的时间。Time task percentage …
我试图在我的Linux机器上创建Wiki的本地精确副本,但无论我尝试什么,它最终都无法正常工作.
挑战在于除了对Wiki的Web访问之外我没有访问权限,但仅仅拥有当前状态的快照就足够了.我试图使用wget,但它无法正确下载文件,也没有转换这些页面内的链接.
我试图使用websucker.py但又没有正确转换链接,并且因为大多数Wiki文件没有扩展名,所以我无法将我的网络服务器(lighttpd)作为text/html提供.
有没有人有工作工具或者可以告诉我使用wget或websucker.py来创建现有Wiki的工作克隆的参数?