我有一段简单的Java代码:
public static void main(String[] args) {
String testStr = "test";
String rst = testStr + 1 + "a" + "pig" + 2;
System.out.println(rst);
}
Run Code Online (Sandbox Code Playgroud)
使用Eclipse Java编译器对其进行编译,然后使用AsmTools检查字节码。表明:
该方法中包含三个局部变量。参数位于插槽0中,并且代码假定使用插槽1和2。但是我认为2个局部变量就足够了-索引0仍然是参数,并且代码仅需要一个变量。
为了查看我的想法是否正确,我编辑了文本字节码,将局部变量的数量减少到2,并调整了一些相关指令:
我用AsmTools重新编译了它,效果很好!
那么,为什么Javac或Eclipse编译器不进行这种优化以使用最小局部变量呢?
我从某个地方知道逻辑和:'&&'的优先级高于逻辑或:'||' 在java.And编程时我很少犯错误.但到目前为止,我没有找到关于这种优先权如何真正起作用的任何线索?如果我不知道两者的优先级以及我会犯下什么错误会怎么样?我试着编写一些代码来证明'&&'和'||'的优先级 但失败了,例如:
boolExp1 || boolExp2 && boolExp3 || boolExp4
Run Code Online (Sandbox Code Playgroud)
无论"&&"和"||"的优先级如何,上面的代码都会产生相同的结果,即'false || false && true || 无论优先级是什么,false'结果都是假的.
所以,换句话说,我想要一个方法或函数,可以证明'&&'和'||'的优先级,它应该产生不同的结果取决于'&&'和'||'的优先级......这个功能可以制作吗?有可能吗?我想这可能是一个棘手的问题或一个非常简单的问题......可能不是一个java问题,而是一些数学......总而言之,有人帮忙吗?谢谢.
我从" Scala编程 "一书中了解到,我可以通过编写以下内容来启动scala脚本:
#!/bin/sh
exec scala "$0" "$@"
!#
println("hello world")
Run Code Online (Sandbox Code Playgroud)
没关系,但我也试过这种风格:
#!/usr/bin/env scala
!#
println("hello world")
Run Code Online (Sandbox Code Playgroud)
并发现这个也运行正常.
所以我不知道两者之间有什么区别.
并且,如果两者都好,为什么这本书选择前一个来展示,哪个看起来更长一点?
我使用ASM生成了一些java字节代码.
通过访问模式中的某种小型DSL的某种AST.
我担心生成的字节代码太"直截了当",也就是说,没有任何"编译时优化".
虽然在我的情况下,如果生成的字节代码没有优化,那可能没问题,但我仍然不禁要问:是否需要那些在运行时生成字节代码的项目来进行字节码优化?
我知道,对于jvm,大多数"优化"工作是在程序运行时通过jit编译完成的.因此编译时的字节码优化可能影响很小.
但是,真的吗?对动态生成的字节码进行字节码优化绝对没有意义吗?有没有人可以分享一些关于差异的经验,主要是在运行时性能方面,在有和没有任何形式的优化的字节码之间?
instance Monad (Either a) where
return = Left
fail = Right
Left x >>= f = f x
Right x >>= _ = Right x
Run Code Online (Sandbox Code Playgroud)
'baby.hs'中的代码碎片导致了可怕的编译错误:
Prelude> :l baby
[1 of 1] Compiling Main ( baby.hs, interpreted )
baby.hs:2:18:
Couldn't match expected type `a1' against inferred type `a'
`a1' is a rigid type variable bound by
the type signature for `return' at <no location info>
`a' is a rigid type variable bound by
the instance declaration at baby.hs:1:23
In the …Run Code Online (Sandbox Code Playgroud) 我以一种虚拟语言为例:它只接受一个或多个“!”。它的词法分析器和语法规则是:
grammar Ns;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
NOTS;
}
@header {
package test;
}
@lexer::header {
package test;
}
ns : NOT+ EOF -> ^(NOTS NOT+);
NOT : '!';
Run Code Online (Sandbox Code Playgroud)
好的,如您所见,这代表一种接受“!”的语言 或者 '!!!' 或者 '!!!!!'...
我定义了一些有意义的类来构建 AST:
public class Not {
public static final Not SINGLETON = new Not();
private Not() {
}
}
public class Ns {
private List<Not> nots;
public Ns(String nots) {
this.nots = new ArrayList<Not>();
for (int i = 0; i < nots.length(); i++) …Run Code Online (Sandbox Code Playgroud) 我正在使用 ASM 3.1 生成一个虚拟类。它只有一个简单的构造函数,没有其他方法:
public class TestAsm {
public static void main(String... args) throws Throwable {
ClassWriter sw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
sw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, "test/SubCls", null, "test/SuperCls", null);
sw.visitField(Opcodes.ACC_PUBLIC, "i", "I", null, null);
MethodVisitor mv = sw.visitMethod(0, "<init>", "()V", null, null);
// mv.visitMaxs(2, 1);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "test/SuperCls", "<init>", "()V");
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitInsn(Opcodes.ICONST_2);
mv.visitFieldInsn(Opcodes.PUTFIELD, "test/SubCls", "i", "I");
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();
sw.visitEnd();
byte[] cls = sw.toByteArray();
FileOutputStream fos = new FileOutputStream("bin/test/SubCls.class");
fos.write(cls);
fos.close();
SuperCls o = (SuperCls) Class.forName("test.SubCls").newInstance(); …Run Code Online (Sandbox Code Playgroud)