Compare performances converting 2-D array to string 比較將二維陣列轉為字串速度

In Golang with basic, multithread, string.Join and combinations.

package main

import (
    "fmt"
    "strconv"
    "strings"
    "sync"
    "time"
)

func arrayToStringMT(arr [][]int32) string {
    var sb strings.Builder
    var wg sync.WaitGroup

    // Use a slice to store results in the correct order
    results := make([]string, len(arr))

    for i := 0; i < len(arr); i++ {
        results[i] = ""
        wg.Add(1)
        go func(index int, row []int32) {
            defer wg.Done()

            var rowStr strings.Builder

            for j, value := range row {
                rowStr.WriteString(fmt.Sprintf("%d", value))

                // Add comma except for the last element in a row
                if j < len(row)-1 {
                    rowStr.WriteString(", ")
                }
            }

            // Store the result in the correct index
            results[index] = rowStr.String()
        }(i, arr[i])
    }

    wg.Wait()

    // Concatenate the results in the correct order
    for i, result := range results {
        sb.WriteString(result)

        // Add newline except for the last row
        if i < len(arr)-1 {
            sb.WriteString(", ")
        }
    }

    return sb.String()
}

func arrayToStringBasic(arr [][]int32) string {
    var sb strings.Builder

    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr[i]); j++ {
            sb.WriteString(fmt.Sprintf("%d", arr[i][j]))

            // Add comma except for the last element in a row
            if j < len(arr[i])-1 {
                sb.WriteString(", ")
            }
        }

        // Add newline except for the last row
        if i < len(arr)-1 {
            sb.WriteString(", ")
        }
    }

    return sb.String()
}

func arrayToStringJoin(arr [][]int32) string {
    finalArr := make([]string, len(arr))
    for i := 0; i < len(arr); i++ {
        strArr := make([]string, len(arr))
        for j, value := range arr[i] {
            strArr[j] = strconv.Itoa(int(value))
        }

        // Join the string representations with a separator (e.g., ", ")
        finalArr[i] = strings.Join(strArr, ", ")
    }

    return strings.Join(finalArr, ", ")
}

func arrayToStringJoinMT(arr [][]int32) string {
    var wg sync.WaitGroup

    finalArr := make([]string, len(arr))
    for i := 0; i < len(arr); i++ {
        finalArr[i] = ""
        wg.Add(1)

        go func(index int, arrRow []int32) {
            defer wg.Done()
            strArr := make([]string, len(arr))
            for j, value := range arrRow {
                strArr[j] = strconv.Itoa(int(value))
            }

            // Join the string representations with a separator (e.g., ", ")
            finalArr[index] = strings.Join(strArr, ", ")
        }(i, arr[i])
    }
    wg.Wait()

    return strings.Join(finalArr, ", ")
}

func main() {
    arr := [][]int32{
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 25, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 25, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25},
        {0, 0, 0, 0, 0, 25, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 25, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0, 8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
        {5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 15, 0, 5, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 15, 0, 5, 0, 0},
        {3, 3, 0, 0, 0, 5, 3, 5, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 3, 5, 3, 3, 0, 0, 0, 5, 3, 5, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 3, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0, 8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 12, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 12, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 25, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 25, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25},
        {0, 0, 0, 0, 0, 25, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 25, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0, 8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
        {5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 15, 0, 5, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 15, 0, 5, 0, 0},
        {3, 3, 0, 0, 0, 5, 3, 5, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 3, 5, 3, 3, 0, 0, 0, 5, 3, 5, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 3, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0, 8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 12, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 12, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
        {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0, 5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    }
    // arr := [][]int32{
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 24, 0, 5, 0, 0},
    //  {0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24},
    //  {0, 0, 0, 0, 0, 24, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {0, 0, 0, 0, 0, 9, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
    //  {5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 15, 0, 5, 0, 0},
    //  {3, 3, 0, 0, 0, 5, 3, 5, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 3, 5},
    //  {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {8, 8, 5, 5, 5, 0, 3, 0, 0, 0, 8, 18, 3, 0, 5, 15, 0, 5, 3, 0},
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    //  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
    //  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    //  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0},
    //  {0, 0, 0, 0, 0, 12, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {0, 0, 0, 0, 0, 9, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
    //  {5, 5, 9, 9, 5, 0, 0, 0, 0, 0, 5, 15, 0, 0, 5, 22, 0, 5, 0, 0},
    // }

    // arr := [][]int32{
    //  {1, 2, 3},
    //  {4, 5, 6},
    //  {7, 8, 9},
    // }

    result := ""
    start := time.Now().UnixMilli()
    for i := 0; i < 100000; i++ {
        result = arrayToStringMT(arr)
    }
    end := time.Now().UnixMilli()
    // fmt.Println(result)
    fmt.Println("time: " + strconv.Itoa(int(end-start)))

    start = time.Now().UnixMilli()
    for i := 0; i < 100000; i++ {
        result = arrayToStringBasic(arr)
    }
    end = time.Now().UnixMilli()
    // fmt.Println(result)
    fmt.Println("time: " + strconv.Itoa(int(end-start)))

    start = time.Now().UnixMilli()
    for i := 0; i < 100000; i++ {
        result = arrayToStringJoin(arr)
    }
    end = time.Now().UnixMilli()
    // fmt.Println(result)
    fmt.Println("time: " + strconv.Itoa(int(end-start)))

    start = time.Now().UnixMilli()
    for i := 0; i < 100000; i++ {
        result = arrayToStringJoinMT(arr)
    }
    end = time.Now().UnixMilli()
    // fmt.Println(result)
    fmt.Println("time: " + strconv.Itoa(int(end-start)))
}

input 是 2 dimensions integer array, 會將所有 element 以逗號分隔連接起來成為一個字串。

以結果來看,如果這個 2 dimensions array 不夠大的話,用 strings.Join 會是最快的方式,用 multithread 還不見得有比較好

# 3x3
time: 245 #multi thread
time: 39 #basic
time: 27 #string join
time: 191 #string join + multithread

# 20x20
time: 1770
time: 1495
time: 457
time: 1106

# 40x40
time: 4689
time: 5682
time: 2186
time: 2717