Back in February, I rewrote the compare() function of my Perl script duplicatecode.pl in C using Inline::C. The original pure-Perl version ran in 8 hours, 38 minutes, and 27 seconds, measured with NYTProf.[1] The C version runs in 5 minutes and 10.699 seconds, measured with the time command in bash.
Times for one run each
Time for pure-Perl compare: 31107s (81765s)[2]
Time for C compare: real 5m10.699s user 4m23.250s sys 0m18.813s
Why is the pure-Perl version so slow? Because substr has to do a bunch of checks on the type of variable it is accessing and validate arguments, whereas the C version only needs to do a dereference to get the character at a certain position in a string.
Here are the pure-Perl and C versions:
#pure-Perl
sub compare {
my ($line1, $line2) = @_;
#Both blank strings
if ($line1 eq '' && $line2 eq '') {
return 1.0;
}
#Prevent division by zero when dividing by shortest string later on
elsif ($line1 eq '' || $line2 eq '') {
return 0.0;
}
my $same = 0;
my $total = length($line1) + length($line2);
my $shortest = length($line1) < length($line2) ? length($line1) : length($line2);
my $longest = length($line1) > length($line2) ? length($line1) : length($line2);
my $i = 0;
while ($i < $shortest) {
if (substr($line1, $i, 1) eq substr($line2, $i, 1)) {
$same++;
}
else {
for my $j ($i + 1 .. ($shortest-1)) {
if ((substr($line1, $i, 1) eq substr($line2, $j, 1)) ||
(substr($line1, $j, 1) eq substr($line2, $i, 1))) {
$same++;
$i = $j;
last;
}
}
}
$i++;
}
return $same / $longest;
}
__END__
__C__
/* C version */
double compare(char* line1, char* line2) {
/* Both blank strings */
if (strcmp(line1, "") == 0 && strcmp(line2, "") == 0) {
return 1.0;
}
/* Prevent division by zero when dividing by shortest string later on */
else if (strcmp(line1, "") == 0 || strcmp(line2, "") == 0) {
return 0.0;
}
int same = 0;
int total = strlen(line1) + strlen(line2);
int shortest = strlen(line1) < strlen(line2) ? strlen(line1) : strlen(line2);
int longest = strlen(line1) > strlen(line2) ? strlen(line1) : strlen(line2);
int i = 0;
while (i < shortest) {
if (line1[i] == line2[i]) {
same++;
}
else {
for (int j = i + 1;j < shortest - 1;j++) {
if (line1[i] == line2[j] || line1[j] == line2[i]) {
same++;
i = j;
break;
}
}
}
i++;
}
return same/(longest + 0.0);
}
The code I used for profiling the pure-Perl version was:
~/src/glob2> time perl ../duplicatecode/duplicatecode.pl --compareself libgag/src/*.cpp libusl/src/*.cpp libwee/src/*.cpp src/*.cpp
This was measured on bash on openSUSE Leap 15.4 on WSL1 on Windows 10. Hardware used was an MSI GS63 Stealth with the second drive (D:) replaced with 2TB SSD.
The code I analyzed for duplicate code was Globulation 2 master-0.9.5.0-7c23bf87.
As you have seen in this post, rewriting a time-critical subroutine called from the inner loop in C with Inline::C can significantly speed up overall script execution time. However, it requires a C compiler to be available, so it is not completely portable. Neverless, optimizing slow code is good if it means you wait only minutes rather than hours for the results.
My perl version is:
> perl --version
This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-thread-multi
Copyright 1987-2017, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Footnotes:
1. Devel::NYTProf seems to be unable to measure the speed of Inline::C code.
2. According to Devel::NYTProf, which lists the time counted when profiling and total execution time in parentheses.
3. Yes, I know the C version won't work correctly with strings with embedded NUL bytes ('\0'), but this script is intended to analyze source code rather than binary data.
1. Blender Blender is an open-source 3D modeling program. It is free to use, unlike Maya. The models are saved in ".blend" files. Blender used to have a worse interface, but the UI was overhauled a few years ago. Blender plugins can be written in Python. Blender has a game engine included. The logic of the game engine can be defined by drawing lines between logic blocks.
2. Sweet Home 3D Sweet Home 3D can be used to make a model of a house and arrange furniture to see how it would look. It is written in Java.
3. Maya MayaⓇ is a proprietary 3D CAD program by AutodeskⓇ. It uses radial popup menus instead of vertical menus. There is a student & educator edition of MayaⓇ which is free. Otherwise it costs money.
Example of a radial pop-up menu
4. POV-Ray
POV-Ray is another CAD program but this one can be scripted with a DSL (domain-specific language) called scene description language. POV-Ray stands for Persistence of Vision Ray Tracer.
This was originally going to be a list of five CAD programs but Gazebo is a robot simulator instead of a CAD program.
Ps3Magic is a guide and software to install Linux (e.g. Ubuntu) or Windows on a PlayStation 3. Of the Linux distributions listed on their page, Yellow Dog Linux is made specifically for PS3. You can also install Ubuntu instead.
Installing will take from 45 minutes to 2 hours depending on your Internet speed.
A game where you are a marble and have to bounce other marbles into traps/edge of the screen to finish the level. There are powerups that increase your mass so you can hit other marbles farther and speed which makes you move faster. Watch out for spikes and black holes. http://www.ucw.cz/~hubicka/koules/English/
3. Maelstrom
Kind of like asteroids. Shoot asteroids to break them into smaller asteroids. However, this game has powerups to collect and UFOs to avoid. When you see another ship like yours flying around, fly over to it and you get an extra life. Don't shoot the stranded ship or it will just disappear. https://www.libsdl.org/projects/Maelstrom/
4. Kobo Deluxe
An arcade game where the goal is to shoot the yellow or purple circles to make the maze disappear. The blue circles can be shot at to get rid of some maze walls. Shoot everything to increase your score to get more ships. The asteroids in this game can't be destroyed. http://olofson.net/kobodl/index.html
5. Heroes-Tron
This is a game like Tron or Nibbles and has several power-ups. To get to the next level in quest mode, collect enough purple trail +1 power-ups (marked with a capital L and a yellow arrow pointing to the power-up) to have the end of level power-up appear. Normally, it appears when any player is at length 10. Purple power-ups have an effect on you, white power-ups affect all the other players. https://savannah.nongnu.org/projects/heroes/
6. Geki 2
Geki 2 is a shoot-em-up game that has 6 levels each with a unique boss, and after the sixth level, I think it loops back to level 1. There are two power-ups in this game, S and L. S switches your shot type to multiple shots and L changes it to laser; both increase the strength of your attacks if your shot type is already the same as the power-up's shot type. The power-ups are inside the barrels that show up every now and then. I have uploaded the code at https://github.com/Quipyowert2/geki2/ You can also view the original Geki2 homepage on Wayback Machine. I got the code from http://triring.net/ps2linux/games/kxl/kxlgames.html.
7. PowerManga
Another shmup game each gem you collect gives you choices of different ship upgrades rather than powerups. The pink gem causes an explosion. Use arrow keys to move and Ctrl key to choose the currently selected upgrade in the panel on the right.
Zaz is a game where you match three or marbles of the same color which makes them explode and you gain points. The marble grabber moves along a track; click to pick up/place a marble. If the trail of marbles reaches the hole at the end of the track, the level is over. http://zaz.sourceforge.net/
2. Trackballs
Trackballs is a game where you move a marble around a level with various terrain hazards and other marbles that try to push you around. https://github.com/trackballs/trackballs
3. Krank
Krank is a game where you are a chain of three marbles and you have to match the color and shape of each marble with the slightly larger immovable marble with smaller marbles orbiting it. Sometimes you have to build chains of marbles between two of the larger marbles. Having two different types of marbles attached to the larger marble makes the connected marbles get shot quickly in all directions. https://sourceforge.net/projects/krank/
4. XLogical
XLogical is a puzzle game where you have to put four marbles of the same color in each spinner. Right click the spinner to spin it. Left click to release a marble down the attached track. https://changeling.ixionstudios.com/xlogical/
5. Neverball
Neverball is a game where you collect various coins and activate timers and teleporters to finish the level. Blue coins are worth 10 points, red coins 5 points, and yellow coins 1 point. Tilt the floor with the arrow keys or mouse to move the ball. https://github.com/Neverball/neverball
A protein folding game where the object is to fold the most compact protein without any clashes. You can use scripts (called "Recipes" in-game) to help with folding the protein. https://fold.it
2. EteRNA
This is like FoldIt but has RNA strands you have to color. The switch puzzles can be especially difficult. Yellow is adenine, Blue is Uracil, Red is Guanine, Green is Cytosine. In order of bond strength, Guanine-Cytosine bonds are strongest, then Adenine-Uracil, then Uracil-Guanine. https://eternagame.org/web/
3. Phylo
This is a DNA alignment puzzle. Match the same colors in each column with the least horizontal gaps to get the best score. https://phylo.cs.mcgill.ca/
Pushover is a game where you are an ant pushing over a single domino to make the rest of them fall. Starts out somewhat easy then gets harder. The source is at https://domino-chain.gitlab.io/.
2. Fish Fillets NG
Fish Fillets NG is a clone of Fish Fillets. Starts out very easy then gets near impossible when you reach the level Independence Day because there are tons of heavy pipes everywhere which the smaller fish can't lift. Fish Fillets SourceForge page.
3. Enigma
Enigma is a marble puzzle game where you have to hit the same colored Oxyd boxes with your marble while avoiding obstacles that can kill your marble, like water or skull and crossbones elements. You can also push some objects. There is also a "meditation" mode where you control several white marbles and have to get them all into holes (one per hole) at the same time. Enigma homepage
4. Chroma
TODO: Add video
Chroma is a puzzle game that starts out hard and only gets harder. Collect all the stars on the level. The circled blue X represents you. Use the arrow keys to move. Press space to switch to the grey circled X. http://www.level7.org.uk/chroma/