我写了一个简单的基准测试,以便找出当通过按位和数组计算数组时是否可以消除边界检查.这几乎就是所有哈希表的作用:它们计算
h & (table.length - 1)
Run Code Online (Sandbox Code Playgroud)
作为索引table,其中h是hashCode或派生值.该结果表明,边界检查不被淘汰.
我的基准的想法很简单:计算两个值i和j,其中既保证是有效的数组索引.
i是循环计数器.当它被用作数组索引时,边界检查被消除.j计算为x & (table.length - 1),x每次迭代时某些值都在变化.当它被用作数组索引时,边界检查不会被消除.相关部分如下:
for (int i=0; i<=table.length-1; ++i) {
x += result;
final int j = x & (table.length-1);
result ^= i + table[j];
}
Run Code Online (Sandbox Code Playgroud)
另一个实验使用
result ^= table[i] + j;
Run Code Online (Sandbox Code Playgroud)
代替.时间上的差异可能是15%(在我尝试的不同变体中非常一致).我的问题:
j?MarkoTopolnik的回答表明它更复杂,并且不能保证取消边界检查是一种胜利,特别是在他的计算机上,"正常"代码比"蒙面"慢.我想这是因为它允许一些额外的优化,在这种情况下显示实际上是有害的(鉴于当前CPU的复杂性,编译器甚至几乎不知道).
leventov的答案清楚地表明,数组边界检查是在"屏蔽"中完成的,并且它的消除使得代码与"正常"一样快.
Donal Fellows指出这样一个事实,即屏蔽不适用于零长度表,x & (0-1)等于x.因此,编译器可以做的最好的事情是用零长度检查替换绑定的检查.但这是恕我直言仍然值得,因为零长度检查可以轻松地移出循环.
我有python 2.7.3和ipython 1.2启动和运行正常我的Linux系统(ubuntu 12.04),但要安装所需的课程matplotlab的更新版本.
在终端中运行此代码行后
user$ sudo easy_install -U distribute
user$ export PYTHONHOME=/usr/lib/python2.7/
Run Code Online (Sandbox Code Playgroud)
现在,每次我尝试运行python或ipython收到错误消息
ImportError: no module named site
Run Code Online (Sandbox Code Playgroud)
我该如何反转/解决这个问题?我迷路了.我看了其他类似的问题,但没有其他人使用Linux,我不知道该怎么办.
我们知道最终制作字段通常是个好主意,因为我们获得了线程安全性和不变性,这使得代码更易于推理.我很好奇是否有相关的性能成本.
Java内存模型保证了这一点final Field Semantics:
在该对象完全初始化之后只能看到对象引用的线程可以保证看到该对象的最终字段的正确初始化值.
这意味着对于像这样的类
class X {
X(int a) {
this.a = a;
}
final int a;
static X instance;
}
Run Code Online (Sandbox Code Playgroud)
每当线程1创建这样的实例
X.instance = new X(43);
while (true) doSomethingEventuallyEvictingCache();
Run Code Online (Sandbox Code Playgroud)
和线程2看到它
while (X.instance == null) {
doSomethingEventuallyEvictingCache();
}
System.out.println(X.instance.a);
Run Code Online (Sandbox Code Playgroud)
它必须打印43.如果没有final修饰符,JIT或CPU可以重新排序存储(第一个存储X.instance然后设置a=43),线程2可以看到默认初始化值并打印0.
当JIT看到final它显然不会重新排序.但它也必须强制CPU遵守命令.是否存在相关的性能损失?
我的Servler花了很多时间阅读request.getInputStream()和写作response.getOutputStream().从长远来看,这可能是一个问题,因为它阻止一个线程只是读/写字面上每秒几个字节.(*)
我从不对部分请求数据感兴趣,处理不应在请求完全可用之前启动.同样的回应.
我想,异步IO会解决它,但我想知道什么是正确的方法.也许一个servlet 在收集完整个输入之后用一个包装,使用和调用链式servlet 来Filter替换它?ServletInputStreamByteArrayInputStreamrequest.startAsync
请注意,我的意思是避免在慢速servlet流上浪费线程.这与startAsync避免浪费线程等待某个事件的情况不同.
是的,目前这是一个不成熟的优化.
我当前的输入流读取方法没有什么有趣的,但在这里你是:
private byte[] getInputBytes() throws IOException {
ServletInputStream inputStream = request.getInputStream();
final int len = request.getContentLength();
if (len >= 0) {
final byte[] result = new byte[len];
ByteStreams.readFully(inputStream, result);
return result;
} else {
return ByteStreams.toByteArray(inputStream);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是全部,它在数据不可用时阻止; ByteStreams来自番石榴.
正如答案明确指出的那样,在不浪费线程的情况下使用servlet流是不可能的.servlet体系结构和通用实现都没有公开任何允许说"缓冲整个数据并仅在收集所有内容时给我打电话"的内容,尽管他们使用NIO并且可以做到.
原因可能是通常使用像nginx这样的反向代理,这可以做到.nginx默认执行此缓冲,直到两年前才关闭它.
鉴于许多负面答案,我不确定,但它看起来像我的目标
避免在慢速servlet流上浪费线程
实际上是完全支持的:从3.1开始,ServletInputStream.html#setReadListener …
什么Guava类适合线程安全的缓存?我使用了一个组合键,它是动态构建的,所以softKeys()毫无意义,对吧?我在ConcurentLinkedHashMap的某个地方看到了,是不是要走了?它已经在最近发布了吗?对不起请问混乱的方式......
这个问题很老了,通过他的回答可能是浪费时间.很长一段时间,CacheBuilder这是一条路.
随着try-with-resourceJava 7的推出,我很惊讶地看到Lock它还没有被改造成一个AutoCloseable.它似乎相当简单,所以我自己添加如下:
class Lock implements AutoCloseable {
private final java.util.concurrent.locks.Lock _lock;
Lock(java.util.concurrent.locks.Lock lock) {
_lock = lock;
_lock.lock();
}
@Override
public void close() {
_lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于一个AutoCloseableReentrantReadWiteLock类,用法如下:
try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
由于这似乎是直接和规范使用自动关闭RAII我认为必须有一个很好的理由这不应该做.有人知道吗?
我需要一个类似ArrayList的结构,只允许以下操作
get(int index)add(E element)set(int index, E element)iterator()由于迭代器在许多地方使用,使用Collections#synchronizedList太容易出错.该列表可以增长到几千个元素并且会被大量使用,所以我很确定,这CopyOnWriteArrayList将太慢了.我会从它开始,以避免过早的优化,但我敢打赌它不会很好.
大多数访问将是单线程读取.所以我问这是什么样的数据结构.
我虽然包装synchronizedList提供同步迭代器的东西会做,但它不会因为ConcurrentModificationException.对于并发行为,我显然需要后续读取和迭代器可以看到所有更改.
迭代器不必显示一致的快照,它可能会也可能不会看到更新,set(int index, E element)因为此操作仅用于替换具有更新版本的项目(包含一些添加的信息,这与迭代器的用户无关) ).这些项目完全不可变.
我清楚地说明了为什么CopyOnWriteArrayList不这样做.ConcurrentLinkedQueue由于缺乏索引访问权限,因此是不可能的.我只需要几个操作而不是完全成熟ArrayList.因此,除非任何与Java并发列表相关的问题与此问题重复,否则这个问题不是.
我很清楚它的含义RetentionPolicy并且知道它们的作用以及何时使用它们似乎是有意义的.对于我自己的注释,我确切地知道它们是在运行时,类文件中还是仅仅用于编译时需要的.但是,使用库中定义的任何注释,您可以恕我直言.
例如,javax.annotation.Generated意味着标记生成的代码,但它很少有用.由于有更多的AFAIK工具对字节码比与源工作工具工作,这些信息就会消失,可以使用之前它.
由于在运行时缺少注释不会抛出 ClassNotFoundException(不像例如,缺少接口),使用RetentionPolicy.RUNTIME似乎不会造成伤害.还是我错了?
或者节省了几个字节使用不同Retentions 的原因?对我来说,这似乎导致太多问题值得.我错过了什么?
我想知道是否有可能在整个网络中转储整个HTTP请求+响应.
我不想得到方法,路径信息,查询字符串,标题,cookie,正文等等.理论上我可以自己组装原始数据,但是我不需要HTTP库,对吧?
此外,我想准确转储通过线路的字节.
我想要像这张图片中的原始数据
取自本页.
我使用的是当前node.js的HTTP 客户端使用request.它是普通的HTTP(没有HTTPS).
在node.js中安装代理是一种选择,但我并不坚持使用库.我可以想象包装套接字读写函数,但我看不到如何使用套接字.
我想将 Material UICircularProgress组件显示为几乎填满未知大小的父 div 所需的大小。比方说,尺寸应该是0.8 * min(parent_height, parent_width)。我尝试过愚弄max-width什么的,但没有成功。
我可以使用一些useDimension钩子来测量父母的尺寸,但我认为这是最后的手段。一定有一个纯 CSS 解决方案,对吗?
java ×7
annotations ×1
arraylist ×1
asynchronous ×1
auto-close ×1
caching ×1
concurrency ×1
css ×1
dump ×1
guava ×1
html ×1
http ×1
importerror ×1
ipython ×1
linux ×1
material-ui ×1
node.js ×1
optimization ×1
performance ×1
progress-bar ×1
python ×1
raii ×1
reactjs ×1
retention ×1
servlets ×1
ubuntu-12.04 ×1