Letterpress cheating in Rust 0.9

Posted on January 14, 2014 by Tommy McGuire
Labels: rust

With the release of Rust 0.9 last week, I have updated my ports of Jeff Knupp's Creating and Optimizing a Letterpress Cheating Program in Python and re-executed the still-crappy benchmarks.

All of these programs look for all of the words that can be made from a given set of letters, based on the system dictionary. The argument was "asdwtribnowplfglewhqagnbe", which produces 7440 results from my dictionary with a possible 33,554,406 combinations made from those letters.

Results

Performance this time has not changed drastically, in comparison to the Rust 0.8 version. On the other hand, I upgraded the software on my laptop and have new versions of Python and gcc.

Language Program Rust 0.6
Duration
(seconds)
Rust 0.7
Duration
(seconds)
Rust 0.8
Duration
(seconds)
Rust 0.9
Duration
(seconds)
Python alternatives/presser_one.py 49.1 48.6 47.8 39.0
Rust anagrams-hashmap-wide 9.3 15.4 12.1 19.6
Rust anagrams-vectors-wide 11.8 13.1 12.2 16.8
Nimrod alternatives/nimrod_anagrams 12.3
Python alternatives/presser_two.py 12.8 12.6 12.3 11.6
Rust anagrams-vectors 8.0 8.2 11.9 8.1
Rust anagrams-hashmap 6.0 35.5 7.2 7.0
Rust anagrams-hashmap-mmap 4.8 10.6 7.3 6.3
Rust anagrams-djbhash-tasks 6.2
C alternatives/anagrams-vectors 8.0 5.8 5.8 6.0
Python alternatives/presser_three.py 6.0 6.3 6.0 5.8
Rust anagrams-vectors-tasks 27.1 13.8 4.2 4.6
Rust anagrams-djbhashmap 2.8
C alternatives/anagrams-hash 0.9 1.0 1.0 0.9

The various programming languages are:

Major changes this time around are with the *-wide parallel Rust versions, which got somewhat slower. Possibly, this is due to the changes for the libnative/libgreen split; those two programs are somewhat more chatty than the *-tasks Rust programs. (Disconcertingly, I noted that the timings, particularly for those parallel versions, are not as consistent as they have been.) One newcomer is anagrams-djbhashmap, which has a single thread using an insecure implementation of Rust's HashMap trait. I am not sure what happened with anagrams-djbhash-tasks, which should be in the same range as anagrams-vectors-tasks; they use the same style of parallelism, and the faster hashmap implementation should not hurt it.

Changes

The changes for Rust 0.9 were, again, not entirely trivial. I realize that, from the viewpoint of the Rust developers, the language may be stabilizing. But out here, I am not seeing it.

For the moment, I performed the minimal changes to my Rust code in order to get it to compile. With the change to external iterators last time, and the recent changes to the behavior of the do keyword (which surprised me; I had not read anything about it on the mailing list), the guts of the programs are now being called as:


combinations::each_combination(letters, i, |combo| { ... });

To tell the truth, I am not sure if that has performance implications. In the near future, I intend to rewrite each_combination with some other style of interface.

One major, and much-looked-for, change is in the I/O interfaces. The new version is much nicer. (It was in the 0.8 release, under std::rt, although it was not complete.) There are, however, shades of Java:


let path = Path::new("anadict.txt");
let file = File::open(&path);
let mut bufferedFile = BufferedReader::new(file);
for line in bufferedFile.lines { ... }

The other major change was the removal of the M:N (green-threaded) scheduler to a library and the addition of a (native) 1:1 Rust-task-to-O/S-thread scheduler library. At this time, I do not know which is the default, so I don't know what behavior to expect.

There were a host of syntactic changes with Rust 0.9:

Most of the changes are minor, but still are changes.

Some slightly more important changes were:

In "News of the Weird", I think something odd is happening with mutablity and pattern matching.


let dict_file = File::open_mode(&dict_path, Truncate, Write);

match dict_file {
Some(f) => f.write_str( "hello" ),
None => fail!("not a file")
}

results in a "cannot borrow immutable local variable as mutable" error, as expected. But,


let mut dict_file = File::open_mode(&dict_path, Truncate, Write);

match dict_file {
Some(f) => f.write_str( "hello" ),
None => fail!("not a file")
}

also results in a "cannot borrow immutable local variable as mutable" error, and


let dict_file = File::open_mode(&dict_path, Truncate, Write);

match dict_file {
Some(mut f) => f.write_str( "hello" ),
None => fail!("not a file")
}

works, while


let mut dict_file = File::open_mode(&dict_path, Truncate, Write);

match dict_file {
Some(mut f) => f.write_str( "hello" ),
None => fail!("not a file")
}

results in a "variable does not need to be mutable" warning. I need to take this up on the mailing list; it may be a bug.

Speaking of which, complex.rs, the program I wrote to play with Rust's operator overloading traits, is breaking rustc 0.9.


rustc -L . -O complex.rs
task 'rustc' failed at 'index out of bounds: the len is 1 but the index is 1', /home/mcguire/soft/rust/src/rust-0.9/src/librustc/middle/trans/common.rs:1225
error: internal compiler error: unexpected failure
This message reflects a bug in the Rust compiler.
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
note: the compiler hit an unexpected failure path. this is a bug
note: try running with RUST_LOG=rustc=1 to get further details and report the results to github.com/mozilla/rust/issues
task '
' failed at 'explicit failure', /home/mcguire/soft/rust/src/rust-0.9/src/librustc/lib.rs:453

I suspect it has already been fixed.

active directory applied formal logic ashurbanipal authentication books c c++ comics conference continuations coq data structure digital humanities Dijkstra eclipse virgo electronics emacs goodreads haskell http java job Knuth ldap link linux lisp math naming nimrod notation OpenAM osgi parsing pony programming language protocols python quote quotes R random REST ruby rust SAML scala scheme shell software development system administration theory tip toy problems unix vmware yeti
Member of The Internet Defense League
Site proudly generated by Hakyll.