This article is part of a comparison of web frameworks which tries to measure the ease of learning and development for several web frameworks(Rails, Grails, Django and CodeIgniter) with a practical test. In order to learn Ruby, Groovy, Python and PHP, 8 hours were invested in reading documentation and a set of exercises were implemented. Source code of the implementation of the exercises can be seen here. In this article, a comparison based on this learning process and experience is made.
This article has the following structure:
- Comparison of time developing each exercise
- Comparison of readability of the languages
- Comparison of results in benchmarks and lines of code. From the project Computer Language Benchmarks Game
- Conclusions
It is important to notice that the first section can be difficult to understand without knowing about the implemented exercises. Therefore, in case you do not know about them I recommend you to skim it or jump directly to section 2.
Comparison of developing time
Exercise | Ruby | Groovy | Python | PHP |
---|---|---|---|---|
Strings, files and regular expressions | 4,5 | 3 | 2 | 2 |
Numbers set | 4 | 2,5 | 1 | 2 |
Composite Pattern | 1,5 | 1 | 1 | 0,5 |
TOTAL | 10 | 6,5 | 4 | 4,5 |
Table 1 shows a comparison of timings used to implement each exercise with each technology. According to the results, Python is the programming language which required less hours to finish the exercises and Ruby was the one which needed the most. It is important to remember that the order of columns is the order in development. The first programming languages used required more time than the last ones. Python and PHP were the exception.
In the first exercise, Ruby was the first language used to implement. Therefore, at the beginning, it had to be understood the regular expressions and how to use them. For example, Ruby solution to the first exercise uses a regular expression which does not satisfy all the cases, therefore, an exception code had to be written. Nevertheless, in Groovy, the regular expression which satisfies all the cases was used. Python already had a method to separate between words and another method for removing punctuation, which increased the speed in resolving it. PHP solution is close to Python solution.
In the second exercise, in the case of Ruby it was necessary to understand the code blocks well. For the Groovy case it was easier, since Groovy block codes are similar to Ruby. For the Python case it was even easier, since Python has a number set class. When using PHP it had to be programmed in a manner closer to C++.
In the third exercise, Ruby and Python did not support control type argument, hence exceptions had to be written to control type arguments. On the other hand, Groovy and PHP allowed to control type argument. Furthermore, PHP supported abstract classes, therefore the Component class could be implemented as abstract.
Exercise | Ruby | Groovy | Python | PHP |
---|---|---|---|---|
Strings, files and regular expressions | 30 | 27 | 28 | 35 |
Numbers set | 56 | 51 | 28 | 56 |
Composite Pattern | 50 | 48 | 38 | 50 |
TOTAL | 136 | 126 | 94 | 141 |
In table 2, the number of source code lines for each exercise was counted. Python presented the shortest code. The reasons are: Python does not need end statements in block of code, neither it uses curly braces syntax. Furthermore, in the Number Set exercise, it already had a library for implementing it, which resulted in a shorter code. Rest of programming languages are close to each other. PHP presents the longest code. It uses curly braces and does not have any special method for iteration, it uses the for structure which results in more lines. Besides, Ruby and Groovy are really close, but Groovy has control type argument for example, which allows to write less lines in the third exercise.
Based on this analysis and experience, Python presented the best productivity with the least amount of lines of code. Mainly due to the following facts: it provides a complete set of libraries which allowed to solve each exercise quickly and it has a mandatory indentation syntax. Difference in time between Groovy, Ruby and PHP can be a bit tricky, because how to solve the exercises was learnt using Ruby. Furthermore, the programmer had knowledge about how to use PHP because the manner to solve the problems is really similar to C++. Nevertheless, according to the facts PHP presented a high productivity, close to Python.
Readability
In this section, an analysis of readability of each programming language will be made. A comparison between programming languages and the natural languages will be carried out.
In natural language, a predicate is the completest part of a sentence. The subject names the “do-er” or “be-er” of the sentence; the predicate does the rest of the work. There are several types of predicate but it is always composed by a verb which may connect the subject with other modifiers or information. Object-oriented syntax is close to natural language. In the common form object.method(arguments) the object is the subject, the method is the verb and the arguments are the modifiers.
In table 3, different orders are expressed in natural language and their implementations in the different programming languages are shown. Examples have been extracted from the exercise whenever it has been possible.
In the first example, it is shown that Ruby allows to use a structure closer to a subject, the number set; the action, the method; and the question symbol which shows it expects a boolean. Groovy is similar, but it does not allow the ? symbol. In Python and PHP implementation the verb, the method, acts over the subject, in a less object-oriented manner.
In the second example, a structure for collecting inside a list of elements is shown. In this case, Groovy and Ruby are really similar, they both use the iterators and blocks of code, providing a solution really close to natural language. Groovy presents a shorter solution using the it keyword. Python and PHP present a closer syntax to C++. PHP uses the dot to sum strings, which is not as intuitive as the plus.
The third example is similar to the first one. Ruby uses the ! symbol to make reference to a method which will change the state of the object. Groovy uses an object-oriented manner and closer to natural language but does not use the exclamation symbol. In this case, Python is closer to natural language than before. PHP still uses the verb, function over the object.
Finally, the fourth example shows the ability of Ruby to use the unless statement.
Natural Language | Code Examples | |
---|---|---|
Is the list of numbers empty? | Ruby @theNumberSet.empty? Python len(self.the_set) |
Groovy numbersMap.size() == 0 PHP count($this->arrayset); |
Collect names of each element and write them in a paper called result. | Ruby @composite.each{ |item| result+=item.toString } Python for element in self.listComponents: string += element.toString() |
Groovy components.each{ string += it } PHP foreach ($this->list as $element){ $string .= $element->__toString(); } |
Remove white spaces from the line | Ruby line.chomp! Python line = line.rstrip() |
Groovy Line.trim() PHP $word = trim($word); |
If variable is not a component type, throw an exception. | Ruby raise ‘No component type’ unless component.kind_of?(Component) Python if not isinstance(component,Component): raise NameError(“No component type”) |
In table 3 a list of capabilities which make a language readable are shown. They are extracted from the experience developing these exercises and the website. Python is supposed to be highly object oriented, but it has been seen some examples where Ruby and Groovy are more object-oriented than Python. Furthermore, Python is the only programming language which considers indentation mandatory, which is a good feature for improving readability. The fifth feature shows languages which support keyword arguments. This feature was added to Ruby in version 2.0. It increases readability since it is not necessary to remember the order of the arguments for a method, instead it can be used named arguments.
Feature | Example | Ruby | Groovy | Python | PHP |
---|---|---|---|---|---|
Highly object oriented | 3.times{ puts ’hello’ } | yes | yes | almost | no |
It allows to use ? And ! in methods | line.chomp! | yes | no | no | no |
Unless and until statements | println ’hello’ unless dont knowhim |
yes | no | no | no |
It uses block codes and iterators | listnumbers.each{|number| print number } |
yes | yes | no | no |
Indentation is mandatory and is used to delimit blocks of code |
– | no | no | yes | no |
Keyword arguments. Arguments for a method can be passed by a name | travel(from=’pointa’, to=’pointb’) | yes | no | yes | no |
Based on these examples and the experience developing, Ruby is considered to be the closest to the natural language because it has special syntax features. Groovy will be the second, Python the third, and PHP the last one.
Performance
In this subsection a brief analyses of performance for each programming language will be made. Results in figure 1, shows that Ruby, PHP and Python are similar in performance. Groovy is not shown. But Groovy is considered to be 8 times slower than Java. Hence, it would be around 10 20 times slower than C.

Figure 2 shows difference in execution time, memory and lines of code of Python over Ruby for 10 tiny examples. It is important to notice that Ruby and Python are similar in lines of code in these examples. In some examples Python is shorter and in others larger.

Conclusions
Doing these exercises allows to have some level of experience with the different programming languages. It is difficult to measure productivity, due to the fact that the first implementation is when the first solution for the problem is described, hence it requires more time. Nevertheless, the next conclusions are extracted:
- Python was the most productive language. Mainly due to the existence of libraries. It was the most concise too. It is important to remember that in The Computer Language Benchmark Game: Ruby and Python were similar in lines of code.
- Ruby is the most readable language. Groovy is really similar to Ruby. Python presents new syntax features which are not common in C++, while PHP is really close to C++, hence less readable.
- Groovy presents the best performance. PHP, Python and Ruby have a similar performance.
Those are the conclusions from this experience.
In my opinion:
- Ruby is the most readable language, I really like it, I think its semantics and syntax is the way to go. I just miss the mandatory indentation from Python.
- Python has libraries for almost everything. It is not only something I have observed from this set of exercises. I have talked with colleagues about this topic and they agree Python has loads of libraries, specially about scientific computing. Furthermore, it is said it is well prepared to call C or C++ functions within Python. This feature allows you not to care about performance while developing and, if it is necessary, to make profiling at the end and to translate the parts of code which require more time to be executed. Nevertheless, it is not as readable as Ruby neither as object oriented and it does not have the same performance as Groovy.
- Groovy is really similar to Ruby but it is not the same. Nevertheless, it has a better performance. Furthermore, you can develop in Groovy and call functions in Java. This allows to have the same methodology than with Python and C/C++.
- PHP was designed for web development. Its syntax is really close to C++ but it is easier. It is fine for web development in case you do not want to use a web framework. Furthermore, WordPress, Joomla, Drupal, Moodle among others are build with this language. Hence, if you are planning to make a web project which adapts to those CMS, you will need to learn PHP to modify its behavior.
What do you think about this comparison? Which language do you think is more productive? and readable? What about the performance? Do you agree with my opinion?
Thanks for reading. Comments, criticism and sharing will be appreciated.
Comparison of programming languages: Ruby, Groovy, Python and PHP: Time developing, readability, performance. http://t.co/lwTnIipDNF
excellent comparison!
Very helpful, thanks a lot!
result = ”.join([item.toString() for item in self.listComponents]) 🙂
Incidentally, I don’t find Ruby nearly as readable as Python. Too many Perl-isms.
Very good comparison. For a new person in the world of programming, RUBY is the best considering all aspects. Coding examples made it clear. Thanks
I think this is a great article, until you get to the actual performance results… Take note that you make an assumption on Groovy performance, but you have hard values for Ruby and Python. You assume “But Groovy is considered to be 8 times slower than Java. Hence, it would be around 10 20 times slower than C.” who considers it that? the “authorities”? Where’s the evidence? I could respond with Cython is considered to be equal to performance of C… therefore Cython wins. In order to really prove the driving point of this article you need to compare apples to apples.
If you are using real performance data, the same source, using the same tests needs to cover each language. To make an assumption about Groovy, then use real data from a source comparing Python and Ruby makes the whole premise of this post fragile. I still would like to see real comparisons.
I assumed than Groovy is considered 8 times slower than Java according to what I had read in other articles. I do not remember the location of the articles but they were not as accurate as the CLBG. So, you are right, there is no evidence, just assumption based on what I read.
Unfortunately, I did not find benchmarks for Groovy.
The benchmark at http://www.techempower.com/benchmarks/ is comparing Grails to other web frameworks in some tests. Maybe you would like to take a look at it.
Thanks for your comment.
What a load of garbage! you can’t compare languages based on a programmer who does not know how to use the language.
A better comparison would have been to get a guru of each language to write program exercises.
No OOP techniques were used in the OOP languages – only procedural techniques (I am guessing because it was a C programmer who does not know OOP). In Ruby everything is an object so that “line.split(‘ ‘)” returns an arrray (which is an object and has method map!) likewise with blocks { } they return values (objects) so have methods in this case join(‘ ‘).
based on the english description and example of problem 1 you have it back the front – the [] go around the words that are NOT in the dictionary except if it is an email.
I think Ruby is harder to learn but more capable once you know it.
I am learning Ruby and am no guru, but I wrote the first.rb in 23 lines or 19 sloc (including comments) e.g.
AN_EMAIL_ADDRESS = /([\w-]+(\.[\w-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,4}))/
def square_brackets(word)
# one or more characters except ,. and white space
word.gsub(/([^,.\s]+)/,'[\1]’)
end
def needs_action(word)
word =~ AN_EMAIL_ADDRESS ? “{#{word}}” : square_brackets(word)
end
# create a dictionary hash for loookup (using supplied file “dictionary”)
dictionary = Hash.new
File.foreach(‘dictionary’) { |line| dictionary[line.chomp] = true }
output_file = File.new(‘output’,File::CREAT|File::WRONLY)
# split line into an array of words, process each word, then join back into a single string, then output
File.foreach(‘input’) do |line|
output_file.puts line.split(‘ ‘).map! { |word|
dictionary.has_key?(word) ? word : needs_action(word)
}.join(‘ ‘)
end
output_file.close
Note long lines were folded, blank lines removed and indent removed by the post. I think my version is more easily understood with less comments (the goal of Ruby).
Oh and also Ruby has a set class library already so the second exercise is pointless in Ruby. you need just one line:-
require ‘set’
if you must have the same method names then you just need to alias the existing ones. Obviously this can be done in far less lines of code than your example.
Ruby can do example 3 without defining anything (with different method names). It has this capability already – an array
Thank you Glenn for all the information.
I am sorry you did not find this project really interesting. Other people have found it interesting.
I explained at the beginning of the article which is the context of the comparison.
Maybe a better approach would have been to find gurus of each programming language but it was not the one chosen. The results of the project are more suitable for comparing the ease of learning.
I encourage you to carry out other comparison, looking for gurus for example, to see the results.
Codewars is a nice place to see problems and different solutions in Javascript and Ruby so far, coming more new languages. You could take a look at that.
Thats fine to compare how easy or hard a language is to learn, but you draw conclusions other than that. From what I am reading Ruby is easy to learn and be a bad Ruby programmer. But to be a good Ruby programmer you need to learn the “Ruby way” of programming. And that is more challenging. Don’t get me wrong, for 8 hours of learning the programmer has done well. But as Ruby code goes (judged on what I read from Ruby guru’s and have learned so far), it’s really bad. But I have spent a lot more than 8 hours learn Ruby.
Looking at problem 2 and 3, in the real world you would not need to write any new classes as Ruby has these classes or capabilities in the base language or in libraries. For problem 3 Ruby has no need to create the inheritance tree as it is untyped unlike java or C++. The problem has been designed with fixed type languages in mind and really makes no sense as a challenge in ruby. You would never write code with this kind of syntax ( xxx.addyyyyy() ) in Ruby. You would rather have xxx += yyy or xxx << yyy. To judge readability of the language when forced to conform to other languages syntax is not a fair comparison at all.
Oh one other thing, why didn’t you have each language be the first at a problem, this would have evened the time taken to understand the problem (and solution) over each language.
I was not comparing how easy or hard a language is to learn. This development with the different exercises and programming languages is part of a comparison of web frameworks as described at the beginning of the article. The comparison of the programming languages is made based on this experience.
It is true what you say about problem 2, but after reading the documentation I did not know the existence of those libraries.
I agree that including the problem 3 in the set was not the right decision.
First of all, I think that readability of the languages is a topic subjective. Keeping this in mind, in my opinion, an object oriented language in general allows to make something more readable. Mainly because of writing a sentence in a form object.method(arguments) it is close to the subject.verb arguments and close to the language.
If you have in mind any other way of comparing readability of languages that you think is better, I encourage you to do it and share it with us.
@composite.each{ |item|
result+=item.toString
}
can be done as
result = @composite.map { |s| s.to_s }.reduce(:+)
Groovy:
numbersMap.size() == 0
this can be done like this:
numbersMap.isEmpty()
And this:
components.each{
string += it
}
is the same as this in Groovy
String string = components.join()
You can use join() in Ruby too.
The following is most certainly not Python.
Python
for element in self.listComponents:
string += element.toString()
This can be accomplished succinctly (though perhaps less readably) via:
”.join([str(element) for element in list_components])