In my machine the following D code compiled with release flag and LDC performs over 230ms while the similar Go code performs under 120ms.

string smallestRepr(const string arg) {
        import std.format : format;

        const repeated = format!"%s%s"(arg, arg);
        string result;
        result.reserve(arg.length);
        result = arg;
        foreach (i; 1 .. arg.length) {
                const slice = repeated[i .. i + arg.length];
                if (slice < result)
                        result = slice;
        }
        return result;
}

unittest {
        assert("cba".smallestRepr() == "acb");
}

void main(const string[] args) {
        string[][const string] wordTable;
        import std.stdio : writeln, lines, File;

        foreach (string word; File(args[1]).lines()) {
                word = word[0 .. $ - 1]; // strip the newline character
                const string key = word.smallestRepr();
                if (key in wordTable)
                        wordTable[key] ~= word;
                else
                        wordTable[key] = [word];
        }

        foreach (key; wordTable.keys) {
                if (wordTable[key].length == 4) {
                        writeln(wordTable[key]);
                        break;
                }
        }
}

---

package main

import (
        "bufio"
        "fmt"
        "os"
)

func canonicalize(s string) string {
        c := s + s[:len(s)-1]
        best := s
        for i := 1; i < len(s); i++ {
                if c[i:i+len(s)] < best {
                        best = c[i : i+len(s)]
                }
        }
        return best
}

func main() {
        seen := make(map[string][]string)

        inputFile, err := os.Open(os.Args[1])
        defer inputFile.Close()

        if err != nil {
                os.Exit(1)
        }

        scanner := bufio.NewScanner(inputFile)

        for scanner.Scan() {
                word := scanner.Text()
                n := canonicalize(word)
                seen[n] = append(seen[n], word)

        }

        for _, words := range seen {
                if len(words) == 4 {
                        fmt.Printf("%v\n", words)
                        break
                }

        }
}

The input file : https://raw.githubusercontent.com/dolph/dictionary/master/enable1.txthttps://raw.githubusercontent.com/dolph/dictionary/master/enable1.txt

Problem description: https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching

Where am I losing performance?

Reply via email to