Просто заметьте, я программировал долгое время, но я программировал GO в течение примерно четырех часов относительно этого поста.
Это стало немного академическим c вопросом Теперь все зависит от скорости.
Задача состояла в том, чтобы проанализировать очень большой текстовый файл. Скажем, для тестирования 500 Мб, это не так уж и много, но достаточно, чтобы показать разницу в скорости. Допустим, файл real имеет размер 1 Гб, просто чтобы добавить некоторые параметры к этому замечанию. У меня достаточно памяти для загрузки всего файла в память, если это необходимо.
Вывод ( в данном случае на консоль) каждая строка, которая начинается с определенного IP-адреса c.
Мне было интересно, можно ли это сделать гораздо быстрее, чем grep и awk (et c) написав очень точный c код.
Я решил попробовать это сначала GO, а затем RUST (еще не пробовал).
После некоторой работы с GO I Я весьма удивлен тем, насколько медленнее он делает что-то очень конкретное c. Grep почти на 50% быстрее.
Примечание. Я использовал некоторые базовые c встроенные GO временные характеристики, которые являются точными ( достаточно ) для моих целей.
Я также попытался указать несколько битов источника, которые я не записал, специфицируя c для чтения байтов. Я только 80% понял синтаксис, но они были даже медленнее, чем моя правда кода.
Если вы видите какие-либо несвязанные GO ошибки, не стесняйтесь указывать на них и объяснять, как я говорю, я программирую GO около четырех часов.
Мне нравится кое-что из GO пытается это сделать, поэтому было бы здорово, чтобы это работало даже со скоростью, по крайней мере, равной, в основном, grep и awk et c.
Edit этот тест был на самом деле egrep работает в Ubuntu, так как кажется, что этот код на самом деле быстрее, чем grep и egrep в OSX.
Пока что я достиг поста:
package main
import (
"bufio"
"flag"
"fmt"
"os"
"time"
)
var (
filePath = flag.String("filepath", "", "The path and filename of the file to parse.")
ipAddress = flag.String("ipaddress", "", "The ip address to search for.")
)
func main() {
flag.Parse()
flag.VisitAll(func(f *flag.Flag) {
if f.Value.String() == "" {
fmt.Println()
fmt.Println("Ip address finder.")
fmt.Println()
fmt.Println(`Usage: ipfinder -filepath "..." -ipaddress "..."`)
fmt.Println()
os.Exit(1)
}
})
timerStart := time.Now()
file, err := os.Open(*filePath)
if err != nil {
fmt.Printf("Failed to open file: %s", err)
os.Exit(1)
}
defer file.Close()
fileScanner := bufio.NewScanner(file)
// Stop re-calculating length.
// The compiler may handle this??
var ipAddressStringLength int = len(*ipAddress)
var fileScannerText string
for fileScanner.Scan() {
fileScannerText = fileScanner.Text()
// I took this from the strings.HasPrefix source code and
// tried to exclude bits (that may crash some input) but
// it didn't make much difference.
if fileScannerText[:ipAddressStringLength] == *ipAddress {
fmt.Println(fileScannerText)
}
}
// Not sure about this??
if err := fileScanner.Err(); err != nil {
fmt.Println(err)
}
elapsed := time.Since(timerStart)
fmt.Println()
fmt.Printf("Time Took %s", elapsed)
}