Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何使用pprof优化CSV加载程序?_Regex_Csv_Go_Concurrency - Fatal编程技术网

Regex 如何使用pprof优化CSV加载程序?

Regex 如何使用pprof优化CSV加载程序?,regex,csv,go,concurrency,Regex,Csv,Go,Concurrency,我试图优化CSV加载过程,基本上就是在一个大的CSV文件中进行正则表达式搜索(+4GB-31033993条记录用于我的实验) 我设法构建了一个多处理逻辑来读取CSV,但当我使用pprof分析CPU配置文件时,我认为我的正则表达式搜索没有得到优化。你能帮我改进这段代码,让它能更快地读取CSV吗 以下是我目前的代码: package main import ( "bufio" "flag" "fmt" "log" "os" "regexp"

我试图优化CSV加载过程,基本上就是在一个大的CSV文件中进行正则表达式搜索(+4GB-31033993条记录用于我的实验) 我设法构建了一个多处理逻辑来读取CSV,但当我使用
pprof
分析CPU配置文件时,我认为我的正则表达式搜索没有得到优化。你能帮我改进这段代码,让它能更快地读取CSV吗

以下是我目前的代码:

package main

import (
    "bufio"
    "flag"
    "fmt"
    "log"
    "os"
    "regexp"
    "runtime"
    "runtime/pprof"
    "strings"
    "sync"
)

func processFile(path string) [][]string {
    file, err := os.Open(path)
    if err != nil {
        log.Println("Error:", err)
    }
    var pattern = regexp.MustCompile(`^.*foo.*$`)
    numCPU := runtime.NumCPU()
    jobs := make(chan string, numCPU+1)

    fmt.Printf("Strategy: Parallel, %d Workers ...\n", numCPU)

    results := make(chan []string)
    wg := new(sync.WaitGroup)
    for w := 1; w <= numCPU; w++ {
        wg.Add(1)
        go parseRecord(jobs, results, wg, pattern)
    }
    go func() {
        scanner := bufio.NewScanner(file)
        for scanner.Scan() {
            jobs <- scanner.Text()
        }
        close(jobs)
    }()

    go func() {
        wg.Wait()
        close(results)
    }()

    lines := [][]string{}
    for line := range results {
        lines = append(lines, line)
    }

    return lines
}

func parseRecord(jobs <-chan string, results chan<- []string, wg *sync.WaitGroup, pattern *regexp.Regexp) {
    defer wg.Done()
    for j := range jobs {
        if pattern.MatchString(j) {
            x := strings.Split(string(j), "\n")
            results <- x
        }

    }
}

func split(r rune) bool {
    return r == ','
}

func main() {
    f, err := os.Create("perf.data")
    if err != nil {
        log.Fatal(err)
    }
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()

    pathFlag := flag.String("file", "", `The CSV file to operate on.`)
    flag.Parse()
    lines := processFile(*pathFlag)
    fmt.Println("loaded", len(lines), "records")
}
主程序包
进口(
“布菲奥”
“旗帜”
“fmt”
“日志”
“操作系统”
“regexp”
“运行时”
“运行时/pprof”
“字符串”
“同步”
)
func进程文件(路径字符串)[]字符串{
文件,错误:=os.Open(路径)
如果错误!=零{
log.Println(“错误:”,err)
}
var pattern=regexp.MustCompile(`^.*foo.*$`)
numpu:=runtime.numpu()
作业:=make(chan字符串,numpu+1)
fmt.Printf(“策略:并行,%d个工人…\n”,numCPU)
结果:=make(chan[]字符串)
wg:=新建(sync.WaitGroup)

对于w:=1;wMatchString查找字符串上的任何匹配项 所以你可以摆脱锚和通配符 在regexp引擎中,两端的通配符通常比较慢

示例显示了go 1.10中的这一点

package reggie

import (
        "regexp"
        "testing"
)

var pattern = regexp.MustCompile(`^.*foo.*$`)
var pattern2 = regexp.MustCompile(`foo`)

func BenchmarkRegexp(b *testing.B) {
        for i := 0; i < b.N; i++ {
                pattern.MatchString("youfathairyfoobar")
        }
}

func BenchmarkRegexp2(b *testing.B) {
        for i := 0; i < b.N; i++ {
                pattern2.MatchString("youfathairyfoobar")
        }
}
$ go test -bench=.
goos: darwin
goarch: amd64
BenchmarkRegexp-4        3000000           471 ns/op
BenchmarkRegexp2-4      20000000           101 ns/op
PASS
ok      _/Users/jsandrew/wip/src/reg    4.031s
package reggie
进口(
“regexp”
“测试”
)
var pattern=regexp.MustCompile(`^.*foo.*$`)
var pattern2=regexp.MustCompile(`foo`)
func BenchmarkRegexp(b*testing.b){
对于i:=0;i
谢谢,这是一个我没有意识到的好技巧。这比阅读行31.606206481s要好得多。
-从这次更改中,你看到了在程序结构中还有什么可以改进的吗?-regrex模式将被动态地输入到更多的分析中,看看下一次尝试什么可能更好苏,我加了个正则表达式标签。