D for project in computational chemistry

Idan Arye via Digitalmars-d digitalmars-d at puremagic.com
Sun Aug 16 06:59:31 PDT 2015


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.


More information about the Digitalmars-d mailing list