У меня огромные проблемы с памятью при использовании регулярных выражений в Go:
Showing top 20 nodes out of 34
flat flat% sum% cum cum%
1.53GB 25.03% 25.03% 1.53GB 25.03% regexp/syntax.(*compiler).inst
1.43GB 23.29% 48.31% 1.43GB 23.29% regexp/syntax.(*parser).newRegexp
1.10GB 17.99% 66.31% 1.10GB 17.99% regexp.onePassCopy
0.53GB 8.67% 74.97% 0.53GB 8.67% regexp/syntax.(*Regexp).Simplify
0.39GB 6.44% 81.41% 0.90GB 14.74% regexp.makeOnePass
0.29GB 4.76% 86.17% 0.29GB 4.76% regexp.newQueue
0.19GB 3.13% 89.30% 0.22GB 3.54% regexp.makeOnePass.func1
0.17GB 2.79% 92.09% 6.10GB 99.54% regexp.compile
0.14GB 2.22% 94.31% 0.25GB 4.09% regexp/syntax.(*parser).collapse
0.14GB 2.21% 96.52% 0.14GB 2.21% regexp/syntax.(*parser).push
0.10GB 1.66% 98.17% 1.80GB 29.37% regexp/syntax.Parse
0.04GB 0.69% 98.86% 0.10GB 1.59% regexp/syntax.(*compiler).init
0 0% 98.86% 6.13GB 100% bicctopostgres/app.Test_prepareRecordsToInsert
0 0% 98.86% 6.10GB 99.54% bicctopostgres/app.TypeIs
0 0% 98.86% 6.10GB 99.54% bicctopostgres/app.evalColumn
0 0% 98.86% 6.11GB 99.74% bicctopostgres/app.getColumnsHeaderData
0 0% 98.86% 1.42GB 23.12% bicctopostgres/app.isDate
0 0% 98.86% 0.61GB 10.00% bicctopostgres/app.isInteger
0 0% 98.86% 1.09GB 17.85% bicctopostgres/app.isReal
0 0% 98.86% 2.98GB 48.58% bicctopostgres/app.isTimestamp
Я создаю программу для анализа CSV-файлов, проверяю каждый столбец, если он пуст, и тип данных ( последний бит делается с помощью регулярных выражений), генерирует Postgres таблицы и загружает записи. Столбцы без данных игнорируются при создании таблиц БД.
Но у меня есть это огромное узкое место, что для 2000 записей я заканчиваю использовать 6 ГБ памяти только для вещей, связанных с регулярными выражениями.
Это пример функции для проверки того, являются ли данные меткой времени:
//isTimestamp returns true if the string is exacly: 9999-99-99 99:99:99.999999 .
func isTimestamp(s *string) bool {
e := `(?i)^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}$`
var isDesired = regexp.MustCompile(e)
return isDesired.MatchString(*s)
}
А затем основная функция, которая проверяет типы:
//TypeIs returns the underlying data type of the string, if it's a string also returns the string length, otherwise is zero.
func TypeIs(s *string) (dataType string, stringLength int) {
if isInteger(s) {
return "INTEGER", 0
}
if isReal(s) {
return "REAL", 0
}
if isDate(s) {
return "DATE", 0
}
if isTimestamp(s) {
return "TIMESTAMP", 0
}
return "TEXT", len(*s)
}
Возможно, мои операторы регулярного выражения слишком плохо? Они работают, но, возможно, это слишком грубая сила.
Какие-нибудь советы? Спасибо!