Je dispose d'un fichier comme ceci:manière optimale à lire simultanément un fichier dans Go
NAME : a280
COMMENT : drilling problem (Ludwig)
TYPE : TSP
DIMENSION: 280
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 288 149
2 288 129
3 270 133
4 256 141
5 256 157
6 246 157
7 236 169
8 228 169
9 228 161
10 220 169
11 212 169
12 204 169
13 196 169
14 188 169
15 196 161
et ainsi de suite ...
Les chiffres sont les cordons pour les villes à résoudre TSP. J'essaye d'écrire ceci à Golang. Maintenant, les instances peuvent être comme 200 villes, voire 40.000 villes. Je veux obtenir la meilleure solution possible, alors j'ai pensé que je devrais traiter ce fichier simultanément. J'ai le code suivant:
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
)
func getCords(queue chan string) {
cords := regexp.MustCompile(`\s*\d+\s+\d+\s+\d+`)
for line := range queue {
if cords.MatchString(line) {
fmt.Println(line)
}
}
}
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
}
// Menu - main program menu
func Menu() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("================== Projektowanie efektywnych algorytmów ==================")
fmt.Println("================== Zadanie nr 1 - Algorytm xyz ==================")
// Wczytywanie pliku z danymi
// Format: Lp. X Y
fmt.Printf("\nPodaj nazwę pliku: ")
fileName, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
readFile(fileName)
}
func main() {
Menu()
}
En fonction getCords
je dois useregex, cuz les fichiers ont tendance à avoir une partie de l'information au début.
Le problème commence à readFile()
. Je lance un goroutine, qui scanne le fichier ligne par ligne et récupère toutes les lignes sur le canal. Bien sûr, l'exécution le lance et va plus loin. Maintenant, le problème est, après l'appel go func()
, je devrais essayer de lire à partir du canal. Les solutions que je trouve sur le SO, et sur Internet sont les suivantes:
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
for i := 0; i < 100; i++ {
go getCords(cords)
}
}
donc te première exécution de getCords serait probablement faire encore rien, parce que le goroutine ne parviendrait pas à obtenir la ligne au canal rapide. Les prochaines itérations feraient probablement le travail, mais le problème est que je dois écrire un certain nombre, comme 100
dans cet exemple, et il peut être trop élevé, donc le canal se fermera comme 10 itérations et après c'est juste une perte de temps ou il peut être trop bas, et alors je ne recevrais tout simplement pas tous les résultats.
Comment résolvez-vous des problèmes comme celui-ci, les gars? Existe-t-il une manière optimale, ou dois-je coller avec certains waitGroups
?
commence par écrire une version séquentielle qui fonctionne, alors, trouver les plus lents parties du programme en utilisant le profilage, commence enfin à ajouter au programme concurrency, dans les endroits appropriés. En outre, https://github.com/AkshanshChahal/TSP-Golang –
Vous n'ouvrez aucun fichier n'importe où dans votre code. 'file: = strings.NewReader (fileName)' ne s'ouvre pas et ne charge pas les données de 'fileName'. 'os.Open' fait cela: https://golang.org/pkg/os/#Open. – abhink