Automatic Java to C++ conversion [duplicate] - java

This question already has answers here:
Does a Java to C++ converter/tool exist? [closed]
(10 answers)
Closed 7 years ago.
Has anyone tried automatic Java to C++ conversion for speed improvements? Is it a maintenance nightmare in the long run?
Just read that is used to generate the HTML5 parsing engine in Gecko http://ejohn.org/blog/html-5-parsing/

In general, automatic conversions from one language to another will not be an improvement. Different languages have different idioms that affect performance.
The simplest example is with loops and variable creation. In a Java GC world, creating objects with new is almost free, and they dive into oblivion just as easily. In C++ memory allocation is (generally speaking) expensive:
// Sample java code
for ( int i = 0; i < 10000000; ++i )
{
String str = new String( "hi" ); // new is free, GC is almost free for young objects
}
Direct conversion to C++ will result in bad performance (use of TR1 shared_ptr as memory handler instead of GC):
for ( int i = 0; i < 10000000; ++i )
{
std::shared_ptr< std::string > str( new std::string( "hi" ) );
}
The equivalent loop written in C++ would be:
for ( int i = 0; i < 10000000; ++i )
{
std::string str( "hi" );
}
Direct translation from a language to another usually ends with the worst of both worlds and harder to maintain code.

The positive point to that conversion is that you will need a proper object oriented design in order to switch from java to C++ (paradigm intersection).
However some people say that coding C++ does not bring speed improvement compared to java code.

Even if that worked, I am not so sure that you will see much speed improvement. Java's Hotspot JIT compiler has become pretty good.

It's nearly impossible to replace the automatic memory-management of Java with a manual memory-management via a program. So you most likely will end up with a program, that has memory leaks or with C++-code that uses a garbage-collector. But a garbage-collector in Java have much more things to rely on (for instance no pointer-arithm,etics), so a garbage-collector in C++ to be safe it has a decreased performance. So your automatic conversion will most likely decrease performance.
Instead try to port it by hand to C++ or optimize the Java-code.

There is hardly a chance that this type of conversion shell lead to better performances. Usually when the JVM is working, it converts most of the code to native machine code. what you are suggesting is converting the Jave code to C++ and from there to native machine code, that is to add an extra phase.
However there are some trivial cases in which some gain may be achived due to the fact that:
1) It takes some time to load the JVM from scratch.
2) It takes some time to do the Jit, when running a very short program, a lot of times, you may prefer to waste this time before running.
3) You may not got the same level of machine code on Java, if you are not running on Server mode. (On server Mode you are expected to get top notch machine code, and also one that is best suited for your own CPU as detected on run-time, that is usually lacking on most C/C++ implantations of programs, and moreover a machine code optimized at run-time)

The languages have such different styles in usage that a mindless conversion would be of little use. An intelligent converter would be next to imposable to write because of the different styles used.
Some Problem areas:
Resource allocation is controlled by 'try{} finally{}' blocks in Java while C++ uses RAII.
Java does exception checking at compile time C++ run-time.
Exceptions are handled differently. Two exceptions:
In Java (last throw is propagated)
In C++ application terminated.
Java has a massive standard library
C++ has all the same functionality you just need to go find it on the web [which is a pain].
Java uses pointers for everything.
A straight unthinking conversion will leave you with a program consisting of just shared_ptr objects.
Anyway with JIT Compilation Java is comparable to C++ in speed.

Speaking of such converters in general, they can't be expected to produce either maintainable or high-performance code, since those generally require having an actual human who understands the language writing the code. What they are very useful for is in making it easy to port languages. Any language with a converter to C, for example, can be swiftly implemented on a wide range of languages. I used f2c in the mid-90s to run a Fortran routine on a Macintosh.
You may or may not have performance improvements if you rewrite the code in C++. You'll probably get a slowdown if you use an automatic converter.

Related

Assembly - Are there any languages other than C and C++ that allow for interaction with Assembly using inline code?

I recently read this document titled Embedded Systems/Mixed C and Assembly Programming
It basically deals with how C and C++ allow the user to use Assembly code via a technique called inline assembly that looks sort of like this:
#include<stdio.h>
void main() {
int a = 3, b = 3, c;
asm {
mov ax,a
mov bx,b
add ax,bx
mov c,ax
}
printf("%d", c);
}
And I was wondering if a similar interaction was possible in other high-level languages like Java, Python and others, or if this was only possible with C and C++.
Yes, D, Rust, Delphi, and quite a few other ahead-of-time-compiled languages have some form of inline asm.
Java doesn't, nor do most other languages that are normally JIT-compiled from a portable binary (like Java's .class bytecode, or C#'s CIL). Code injecting/assembly inlining in Java?.
Memory-safe languages like Rust only allow inline asm in unsafe{} blocks because assembly language can mess up the program state in arbitrary ways if it's buggy, even more broadly than C undefined behaviour. Languages like Java intended to sandbox the guest program don't allow unsafe code at all.
Very high level languages like Python don't even have simple object-representations for numbers, e.g. an integer variable isn't just a 32-bit object, it has type info, and (in Python specifically) can be arbitrary length for large values. So even if a Python implementation did have inline-asm facilities, it would be a challenge to let you do anything to Python objects, except maybe for NumPy arrays which are laid out like C arrays.
It's possible to call native machine-code functions (e.g. libraries compiled from C, or hand-written asm) from most high-level languages - that's usually important for writing some kinds of applications. For example, in Java there's JNI (Java Native Interface). Even node.js JavaScript can call native functions. "Marshalling" args into a form that makes sense to pass to a C function can be expensive, depending on the high-level language and whether you want to let the C / asm function modify an array or just return a value.
Different forms of inline asm in different languages
Often they're not MSVC's inefficient form like you're using (which forces a store/reload for inputs and outputs). Better designs, like Rust's modeled on GNU C inline asm can use registers. e.g. like GNU C asm("lzcnt %1, %0" : "=r"(leading_zero_count) : "rm"(input)); letting the compiler pick an output register, and pick register or a memory addressing mode for the input.
(But even better to use intrinsics like _lzcnt_u32 or __builtin_clz for operations the compiler knows about, only inline asm for instructions the compiler doesn't have intrinsics for, or if you want to micro-optimize a loop in a certain way. https://gcc.gnu.org/wiki/DontUseInlineAsm)
Some (like Delphi) have inputs via a "calling convention" similar to a function call, with args in registers, not quite free mixing of asm and high-level code. So it's more like an asm block with fixed inputs, and one output in a specific register (plus side-effects) which the compiler can inline like it would a function.
For syntax like you show to work, either
You have to manually save/restore every register you use inside the asm block (really bad for performance unless you're wrapping a big loop - apparently Borland Turbo C++ was like this)
Or the compiler has to understand every single instruction to know what registers it might write (MSVC is like this). The design notes / discussion for Rust's inline asm mention this requirement for D or MSVC compilers to implement what's effectively a DSL (Domain Specific Language), and how much extra work that is, especially for portability to new ISAs.
Note that MSVC's specific implementation of inline asm was so brittle and clunky that it doesn't work safely in functions with register args, which meant not supporting it at all for x86-64, or ARM/AArch64 where the standard calling convention uses register args. Instead, they provide intriniscs for basically every instruction, including privileged ones like invlpg, making it possible to write a kernel (such as Windows) in Visual C++. (Where other compilers would expect you to use asm() for such things). Windows almost certainly has a few parts written in separate .asm files, like interrupt and system-call entry points, and maybe a context-switch function that has to load a new stack pointer, but with good intrinsics support you don't need asm, if you trust your compiler to make good-enough asm on its own.
You can inline assembly in HolyC.

Handle Multiple Access to dll function

doingI have a problem while acessing dll functions with multiple threads .
I am using my own-compilated dll . I call a dll function from java (JNA) with multiple java threads .
The operation I am processing is about images processing .
With this method I do observe some little frame generation speed loss.
I am wondering if it is because of the thread access to the dll function .
Here is the function I am using :
__declspec(dllexport) int iterate(double z_r,double z_i,double c_r,double c_i,double maxIteration){
double tmp;
int i=0;
while(z_r*z_r + z_i*z_i < 4 && i <maxIteration){
tmp = z_r;
z_r = z_r*z_r - z_i*z_i + c_r;
z_i = 2*z_i*tmp + c_i;
i++;
}
return i;
}
The problem probably isn't that you are accessing the function from multiple threads, it should be the external access itself. I don't know how big your values for, for example, maxIteration are, but it seems to me that this code snippet doesn't run very long, but often.
Especially when using JNA there's probably some serious overhead when invoking this method. So you should try to do more work at once, before returning to Java (and invoking the external method again...). This way the performance advantages you might have in C could make up for the overhead.
That said, however, it is not sure to say that this method would run faster written in C than written in Java. Without citation at hand at the moment (I will try to find one), I heard in a lecture a few weeks ago that Java is supposed to be amazingly fast when it comes to simple arithmetic operations - and this is the only thing your method does. You should also check if you enabled compiler optimizations when compiling your C library.
Edit: This Wikipedia article states that Java has a performance for arithmetic operations similar to such programs written in C++. So the performance advantage might be slight and the overhead I mentioned before might decide in the end.

Java - calling static methods vs manual inlining - performance overhead

I am interested whether should I manually inline small methods which are called 100k - 1 million times in some performance-sensitive algorithm.
First, I thought that, by not inlining, I am incurring some overhead since JVM will have to find determine whether or not to inline this method (or even fail to do so).
However, the other day, I replaced this manually inlined code with invocation of static methods and seen a performance boost. How is that possible? Does this suggest that there is actually no overhead and that by letting JVM inline at "its will" actually boosts performance? Or this hugely depends on the platform/architecture?
(The example in which a performance boost occurred was replacing array swapping (int t = a[i]; a[i] = a[j]; a[j] = t;) with a static method call swap(int[] a, int i, int j). Another example in which there was no performance difference was when I inlined a 10-liner method which was called 1000000 times.)
I have seen something similar. "Manual inlining" isn't necessarily faster, the result program can be too complex for optimizer to analyze.
In your example let's make some wild guesses. When you use the swap() method, JVM may be able to analyze the method body, and conclude that since i and j don't change, although there are 4 array accesses, only 2 range checks are needed instead of 4. Also the local variable t isn't necessary, JVM can use 2 registers to do the job, without involving r/w of t on stack.
Later, the body of swap() is inlined into the caller method. That is after the previous optimization, so the saves are still in place. It's even possible that caller method body has proved that i and j are always within range, so the 2 remaining range checks are also dropped.
Now in the manually inlined version, the optimizer has to analyze the whole program at once, there are too many variables and too many actions, it may fail to prove that it's safe to save range checks, or eliminate the local variable t. In the worst case this version may cost 6 more memory accesses to do the swap, which is a huge overhead. Even if there is only 1 extra memory read, it is still very noticeable.
Of course, we have no basis to believe that it's always better to do manual "outlining", i.e. extract small methods, wishfully thinking that it will help the optimizer.
--
What I've learned is that, forget manual micro optimizations. It's not that I don't care about micro performance improvements, it's not that I always trust JVM's optimization. It is that I have absolutely no idea what to do that does more good than bad. So I gave up.
The JVM can inline small methods very efficiently. The only benifit inlining yourself is if you can remove code i.e. simplify what it does by inlining it.
The JVM looks for certain structures and has some "hand coded" optimisations when it recognises those structures. By using a swap method, the JVM may recognise the structure and optimise it differently with a specific optimisation.
You might be interested to try the OpenJDK 7 debug version which has an option to print out the native code it generates.
Sorry for my late reply, but I just found this topic and it got my attention.
When developing in Java, try to write "simple and stupid" code. Reasons:
the optimization is made at runtime (since the compilation itself is made at runtime). The compiler will figure out anyway what optimization to make, since it compiles not the source code you write, but the internal representation it uses (several AST -> VM code -> VM code ... -> native binary code transformations are made at runtime by the JVM compiler and the JVM interpreter)
When optimizing the compiler uses some common programming patterns in deciding what to optimize; so help him help you! write a private static (maybe also final) method and it will figure out immediately that it can:
inline the method
compile it to native code
If the method is manually inlined, it's just part of another method which the compiler first tries to understand and see whether it's time to transform it into binary code or if it must wait a bit too understand the program flow. Also, depending on what the method does, several re-JIT'ings are possible during runtime => JVM produces optimum binary code only after a "warm up"... and maybe your program ended before the JVM warms itself up (because I expect that in the end the performance should be fairly similar).
Conclusion: it makes sense to optimize code in C/C++ (since the translation into binary is made statically), but the same optimizations usually don't make a difference in Java, where the compiler JITs byte code, not your source code. And btw, from what I've seen javac doesn't even bother to make optimizations :)
However, the other day, I replaced this manually inlined code with invocation of static methods and seen a performance boost. How is that possible?
Probably the JVM profiler sees the bottleneck more easily if it is in one place (a static method) than if it is implemented several times separately.
The Hotspot JIT compiler is capable of inlining a lot of things, especially in -server mode, although I don't know how you got an actual performance boost. (My guess would be that inlining is done by method invocation count and the method swapping the two values isn't called too often.)
By the way, if its performance really matters, you could try this for swapping two int values. (I'm not saying it will be faster, but it may be worth a punt.)
a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j];
a[i] = a[i] ^ a[j];

Best (scala & other languages that target java vm) optimizations

I was just reading about scala's implementation of generics specialization , and it really caught my attention the increase of speed they achieved with this feature. I was wondering what other features have the languages that target the java vm implemented that actually made them perform better than java? I know that the further the generated code moves away from java, the further its performance drops. So I really wonder what other features can a language implement to achieve better performance in java.
Please don't answer this question talking about scala's really nice features on top of java, I'm talking strictly about performance.
Also if you have suggestions that still weren't implemented, please do answer!
Thank you!
Scala does support tail-call optimization, which Java, through the JVM alone, don't fully support yet.
Scala optimizes things like
val nullSafeToString = "" + foo
to
val nullSafeToString = String.valueOf(foo)
Java doesn't, in Java it looks like
val nullSafeToString = new StringBuilder("").append(foo)
which takes 4 times more bytecode than Scala's simpler code and creates a new StringBuilder instance and an useless String.
On the one side the JVM was made to support the things they had planned to use in Java, even if the JVM only executes bytecode.
There are features which are missing for ages to better support functional (tailcalls) and untyped languages (InvokeDynamic).
But on the other side I'm surprised how painless the JIT compiler can optimize heavily abstracted code and layers of indirection away and end up with code performing as fast as Java code.
I think that "Pimp My Library" pattern wouldn't be that popular if the JVM couldn't remove the instance creations of these simple implicit + class RichFoo patterns with escape analysis.
Maybe this is too trivial/old/well-known but the Java compiler optimizes String literals and concatenations using a String pool and StringBuilders:
String a = "a";
String b = "a";
String c = a + b + someUserInput;
will actually be closer to
String a = "a";
String b = a;
String a_b = "aa";
String c = new StringBuilder(a_b).append(someUserInput).toString();
or maybe even (not sure)
String a_b = "aa";
String a = a_b.substring(0,1);
String b = a;
String c = new StringBuilder(a_b).append(someUserInput).toString();
Also, the focus of optimization for the Java compiler has shifted from compilation to bytecode (javac) to the compilation from bytecode to machine code (Hotspot). I think there used to be more optimizations in javac, but they have found that to be a bit premature given that Hotspot can do a much more thorough job here (and draw on runtime knowledge about actual hardware and usage patterns).
Another interesting aspect of this is that Hotspot optimizations can improve the performance long after the code was written and compiled. For example, the StringBuilder optimization above used to use the (slightly less efficient) StringBuffer class before Java 5. In order to get the latest improvements, you would need to recompile the code (which is still better than having hand-optimized to use StringBuffer before, in which case you would actually need to update the code).

Complexity of Java 7's current Lambda proposal? (August 2010)

Some people say that every programming language has its "complexity budget" which it can use to accomplish its purpose. But if the complexity budget is depleted, every minor change becomes increasingly complicated and hard to implement in a backward-compatible way.
After reading the current provisional syntax for Lambda (≙ Lambda expressions, exception transparency, defender methods and method references) from August 2010 I wonder if people at Oracle completely ignored Java's complexity budget when considering such changes.
These are the questions I'm thinking about - some of them more about language design in general:
Are the proposed additions comparable in complexity to approaches other languages chose?
Is it generally possible to add such additions to a language and protecting the developer from the complexity of the implementation ?
Are these additions a sign of reaching the end of the evolution of Java-as-a-language or is this expected when changing a language with a huge history?
Have other languages taken a totally different approach at this point of language evolution?
Thanks!
I have not followed the process and evolution of the Java 7 lambda
proposal, I am not even sure of what the latest proposal wording is.
Consider this as a rant/opinion rather than statements of truth. Also,
I have not used Java for ages, so the syntax might be rusty and
incorrect at places.
First, what are lambdas to the Java language? Syntactic sugar. While
in general lambdas enable code to create small function objects in
place, that support was already preset --to some extent-- in the Java
language through the use of inner classes.
So how much better is the syntax of lambdas? Where does it outperform
previous language constructs? Where could it be better?
For starters, I dislike the fact that there are two available syntax
for lambda functions (but this goes in the line of C#, so I guess my
opinion is not widespread. I guess if we want to sugar coat, then
#(int x)(x*x) is sweeter than #(int x){ return x*x; } even if the
double syntax does not add anything else. I would have preferred the
second syntax, more generic at the extra cost of writting return and
; in the short versions.
To be really useful, lambdas can take variables from the scope in
where they are defined and from a closure. Being consistent with
Inner classes, lambdas are restricted to capturing 'effectively
final' variables. Consistency with the previous features of the
language is a nice feature, but for sweetness, it would be nice to be
able to capture variables that can be reassigned. For that purpose,
they are considering that variables present in the context and
annotated with #Shared will be captured by-reference, allowing
assignments. To me this seems weird as how a lambda can use a variable
is determined at the place of declaration of the variable rather than
where the lambda is defined. A single variable could be used in more
than one lambda and this forces the same behavior in all of them.
Lambdas try to simulate actual function objects, but the proposal does
not get completely there: to keep the parser simple, since up to now
an identifier denotes either an object or a method that has been kept
consistent and calling a lambda requires using a ! after the lambda
name: #(int x)(x*x)!(5) will return 25. This brings a new syntax
to use for lambdas that differ from the rest of the language, where
! stands somehow as a synonim for .execute on a virtual generic
interface Lambda<Result,Args...> but, why not make it complete?
A new generic (virtual) interface Lambda could be created. It would
have to be virtual as the interface is not a real interface, but a
family of such: Lambda<Return>, Lambda<Return,Arg1>,
Lambda<Return,Arg1,Arg2>... They could define a single execution
method, which I would like to be like C++ operator(), but if that is
a burden then any other name would be fine, embracing the ! as a
shortcut for the method execution:
interface Lambda<R> {
R exec();
}
interface Lambda<R,A> {
R exec( A a );
}
Then the compiler need only translate identifier!(args) to
identifier.exec( args ), which is simple. The translation of the
lambda syntax would require the compiler to identify the proper
interface being implemented and could be matched as:
#( int x )(x *x)
// translated to
new Lambda<int,int>{ int exec( int x ) { return x*x; } }
This would also allow users to define Inner classes that can be used
as lambdas, in more complex situations. For example, if lambda
function needed to capture a variable annotated as #Shared in a
read-only manner, or maintain the state of the captured object at the
place of capture, manual implementation of the Lambda would be
available:
new Lambda<int,int>{ int value = context_value;
int exec( int x ) { return x * context_value; }
};
In a manner similar to what the current Inner classes definition is,
and thus being natural to current Java users. This could be used,
for example, in a loop to generate multiplier lambdas:
Lambda<int,int> array[10] = new Lambda<int,int>[10]();
for (int i = 0; i < 10; ++i ) {
array[i] = new Lambda<int,int>{ final int multiplier = i;
int exec( int x ) { return x * multiplier; }
};
}
// note this is disallowed in the current proposal, as `i` is
// not effectively final and as such cannot be 'captured'. Also
// if `i` was marked #Shared, then all the lambdas would share
// the same `i` as the loop and thus would produce the same
// result: multiply by 10 --probably quite unexpectedly.
//
// I am aware that this can be rewritten as:
// for (int ii = 0; ii < 10; ++ii ) { final int i = ii; ...
//
// but that is not simplifying the system, just pushing the
// complexity outside of the lambda.
This would allow usage of lambdas and methods that accept lambdas both
with the new simple syntax: #(int x){ return x*x; } or with the more
complex manual approach for specific cases where the sugar coating
interferes with the intended semantics.
Overall, I believe that the lambda proposal can be improved in
different directions, that the way it adds syntactic sugar is a
leaking abstraction (you have deal externally with issues that are
particular to the lambda) and that by not providing a lower level
interface it makes user code less readable in use cases that do not
perfectly fit the simple use case.
:
Modulo some scope-disambiguation constructs, almost all of these methods follow from the actual definition of a lambda abstraction:
λx.E
To answer your questions in order:
I don't think there are any particular things that make the proposals by the Java community better or worse than anything else. As I said, it follows from the mathematical definition, and therefore all faithful implementations are going to have almost exactly the same form.
Anonymous first-class functions bolted onto imperative languages tend to end up as a feature that some programmers love and use frequently, and that others ignore completely - therefore it is probably a sensible choice to give it some syntax that will not confuse the kinds of people who choose to ignore the presence of this particular language feature. I think hiding the complexity and particulars of implementation is what they have attempted to do by using syntax that blends well with Java, but which has no real connotation for Java programmers.
It's probably desirable for them to use some bits of syntax that are not going to complicate existing definitions, and so they are slightly constrained in the symbols they can choose to use as operators and such. Certainly Java's insistence on remaining backwards-compatible limits the language evolution slightly, but I don't think this is necessarily a bad thing. The PHP approach is at the other end of the spectrum (i.e. "let's break everything every time there is a new point release!"). I don't think that Java's evolution is inherently limited except by some of the fundamental tenets of its design - e.g. adherence to OOP principles, VM-based.
I think it's very difficult to make strong statements about language evolution from Java's perspective. It is in a reasonably unique position. For one, it's very, very popular, but it's relatively old. Microsoft had the benefit of at least 10 years worth of Java legacy before they decided to even start designing a language called "C#". The C programming language basically stopped evolving at all. C++ has had few significant changes that found any mainstream acceptance. Java has continued to evolve through a slow but consistent process - if anything I think it is better-equipped to keep on evolving than any other languages with similarly huge installed code bases.
It's not much more complicated then lambda expressions in other languages.
Consider...
int square(x) {
return x*x;
}
Java:
#(x){x*x}
Python:
lambda x:x*x
C#:
x => x*x
I think the C# approach is slightly more intuitive. Personally I would prefer...
x#x*x
Maybe this is not really an answer to your question, but this may be comparable to the way objective-c (which of course has a very narrow user base in contrast to Java) was extended by blocks (examples). While the syntax does not fit the rest of the language (IMHO), it is a useful addition and and the added complexity in terms of language features is rewarded for example with lower complexity of concurrent programming (simple things like concurrent iteration over an array or complicated techniques like Grand Central Dispatch).
In addition, many common tasks are simpler when using blocks, for example making one object a delegate (or - in Java lingo - "listener") for multiple instances of the same class. In Java, anonymous classes can already be used for that cause, so programmers know the concept and can just spare a few lines of source code using lambda expressions.
In objective-c (or the Cocoa/Cocoa Touch frameworks), new functionality is now often only accessible using blocks, and it seems like programmers are adopting it quickly (given that they have to give up backwards compatibility with old OS versions).
This is really really close to Lambda functions proposed in the new generation of C++ (C++0x)
so I think, Oracle guys have looked at the other implementations before cooking up their own.
http://en.wikipedia.org/wiki/C%2B%2B0x
[](int x, int y) { return x + y; }

Categories

Resources