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/laha9j$pc$1...@digitalmars.com

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.

Reply via email to