Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Tuesday, April 14, 2009

Comparison of Python vs Java


Here is my experience using Python and Java for software development.

Overall, Python is best for small projects and rapid prototyping. Python has certain advantages with its dynamic nature, but as the code base grows these advantages become disadvantages. Java is best for larger projects and where performance is important. Python performance is poor: bytecode executes slow, and global interpreter lock prevents threads from completely utilizing multiple CPUs.

Python is pleasant to use with its expressive string operations, e.g. you can write 'a'*80 to make a string of 80 'a' characters. Using operators on collections in Python is so much more intuitive than using Java's method-based operations. It's nice to not have to compile files.

However, in Python you can make a typo, and it can be frustrating to catch those. Something that background compilation would catch right away in a Java IDE and highlight as syntax error in 1 second, takes writing unit-tests, getting back to the code you've written not at this minute, and fixing it. Because Python is so permissive you can easily do this:


var = method
for i in var:
do something else

Note that you intended to write:

var = method()

You omitted the braces. Nothing flagged this as a possible error. During execution, the error isn't manifested on the same line, but instead a couple lines after that when we are trying to do
something with a method instead of an object.

Overall it seems that dynamic languages have inherent limitations that limit code discovery. From a practical point of view, modern languages now have huge libraries, and it's impossible for a human to remember even a fraction of library routine names and parameters. So here is where "suggest" or autocomplete functionality comes in nicely. However it's hard to implement in a dynamic language for the simple reason, that you don't know what types objects are. This impacts your productivity severely, as you have to go and check man pages over and over as opposed to having method names pop up as you write code.

In Python writing performant code is hard. Organizing your code into methods has significant performance penalty if these methods are frequently invoked. Python VM doesn't inline. Essentially Python performance trick is making sure you delegate to the C code. Doing work by executing Python code makes things slow. Because of GIL, Python threads don't truly run simultaneously. Instead it is simulated that they run simultaneously. So if you have multiple CPUs and multiple threads you won't utilize all your CPUs.

Click here for the table summarizing Python and Java.
For some reason Blogger puts a large space between the text and the table.




















































FEATURE
PYTHON
JAVA
Rapid prototyping
Yes
Less so
(compile phase)
Suitable for large projects
Less so
hard to refactor (dynamic language)
unreliable debugger
VM crashes
Yes
refactoring support
good debugging support
Scalability
Limited
(runs only one thread at a time because of GIL)
Better
threads run simultaneously
Performance
Slower
VM doesn't inline methods
Performance penalty for method calls.
Faster
Straight bytecode execution about 3 times faster than Python.
Language features

Overall better
collection operators e.g. brackets
expressive string operations
unchecked exceptions
non-default constr.inheritance
default arguments
Overall worse
collections use via methods

pluses over python:
method overloading
Productivity:
Can IDE catch typos?
No
Typos become runtime errors
Most of the time IDE cannot tell an error from valid use

Yes
IDE can compile code in background and highlight typos.
Productivity: IDE:
Refactoring, Suggestions, Autocomplete, Code analysis
Hardly possible
because Python is dynamic
Yes
This makes one write code fast.
IDE can perform mathematically correct refactoring
Debugging
PyDev vs Eclipse
Rudimental
Hard to debug multi-threaded programs: cannot pause all threads
Cannot break on exception
Unreliable
Superior
Business-friendly
Less so
Fewer options as many 3d party libraries tend to be GPL. You may have no option but open sourcing your work.
Harder to close source, as normally open py files are distributed instead of compiled bytecode.
More so
Many 3d party libraries under BSD, Apache, or LGPL licenses.

Monday, November 24, 2008

Script to reuse Eclipse project when switching code directory underneath

We're using subversion transactions here at Snaplogic: when working on a bug fix or new feature we create a branch off main tree, then after the change is complete we merge it into the main tree. Transaction management can be easily automated using shell scripts: tx-begin, tx-commit, etc.

However if you are using Eclipse there is a problem that each time you create a transaction you have to recreate your project. Even though you're working on the code, and have set up your project paths, and environment, and launch configurations, you have to recreate all that when you switch from one transaction to another, because each transaction resides in a different directory.

You want to have transactions in separate directories to be able to go back and forth between them, if you are working on several at a time, and for historical purposes. It may seem that you can overcome this limitation of Eclipse by using symlinks, and you can, to a degree, however Eclipse converts the symlink to the absolute file system path, and stores that in its project file.

So this is the missing piece of the puzzle of reusing the same Eclipse project when switching project directories underneath.

This python script will edit the .location file stored in the .metadata directory of Eclipse's resources plugin.

#!/usr/bin/python
# Pass destination path as the parameter
import sys

LOCATION = "/home/dmitri/workspace/.metadata/.plugins/org.eclipse.core.resources/.projects/code/.location"
PREFIX = "URI//file:"
replace_path = PREFIX + sys.argv[1]
file = open(LOCATION, "rb")
contents = file.read()
start = contents.index(PREFIX)
length = ord(contents[start-1:start])
sys.stdout.write(contents[0:start-2] + chr(0) + chr(len(replace_path)) + replace_path + contents[start + length:])


You run it as follows:

fix-eclipse /home/dmitri/workspace/all-code/dmitri_snaphome-2/snaplogic/python > /tmp/.location
cp /tmp/.location /home/dmitri/workspace/.metadata/.plugins/org.eclipse.core.resources/.projects/code/.location