On Sunday, 16 August 2015 at 13:11:12 UTC, Yura wrote:
Good afternoon, gentlemen,
just want to describe my very limited experience. I have
re-written about half of my Python code into D. I got it faster
by 6 times. This is a good news.
However, I was amazed by performance of D vs Python for
following simple nested loops (see below). D was faster by 2
order of magnitude!
Bearing in mind that Python is really used in computational
chemistry/bioinformatics, I am sure D can be a good option in
this field. In the modern strategy for the computational
software python is used as a glue language and the number
crunching parts are usually written in Fortran or C/C++.
Apparently, with D one language can be used to write the entire
code. Please, also look at this article:
http://www.worldcomp-proceedings.com/proc/p2012/PDP3426.pdf
Also, I wander about the results of this internship:
http://forum.dlang.org/post/[email protected]
With kind regards,
Yury
Python:
#!/usr/bin/python
import sys, string, os, glob, random
from math import *
a = 0
l = 1000
for i in range(l):
for j in range(l):
for m in range(l):
a = a +i*i*0.7+j*j*0.8+m*m*0.9
print a
D:
import std.stdio;
// command line argument
import std.getopt;
import std.string;
import std.array;
import std.conv;
import std.math;
// main program starts here
void main(string[] args) {
int l = 1000;
double a = 0;
for (auto i=0;i<l;i++){
for (auto j=0;j<l;j++) {
for (auto m=0;m<l;m++) {
a = a + i*i*0.7+j*j*0.8+m*m*0.9;
}
}
}
writeln(a);
}
Initially I thought the Python version is so slow because it uses
`range` instead of `xrange`, but I tried them both and they both
take about the same, so I guess the Python JIT(or even
interpreter!) can optimize these allocations away.
BTW - if you want to iterate over a range of numbers in D, you
can use a foreach loop:
foreach (i; 0 .. l) {
foreach (j; 0 .. l) {
foreach (m; 0 .. l) {
a = a + i * i * 0.7 + j * j * 0.8 + m * m * 0.9;
}
}
}
Or, to make it look more like the Python version, you can iterate
over a range-returning function:
import std.range : iota;
foreach (i; iota(l)) {
foreach (j; iota(l)) {
foreach (m; iota(l)) {
a = a + i * i * 0.7 + j * j * 0.8 + m * m * 0.9;
}
}
}
There are also functions for building ranges from other ranges:
import std.algorithm : cartesianProduct;
import std.range : iota;
foreach (i, j, m; cartesianProduct(iota(l), iota(l),
iota(l))) {
a = a + i * i * 0.7 + j * j * 0.8 + m * m * 0.9;
}
Keep in mind though that using these functions, while making the
code more readable(to those with some experience in D, at least),
is bad for performance - for my first version I got about 5
seconds when building with DMD in debug mode, while for the last
version I get 13 seconds when building with LDC in release mode.