reduce number of memory allocations in hot path

This commit is contained in:
Danny van Kooten 2018-07-15 10:05:03 +02:00
parent b2d881e31b
commit 2ef550bc27
2 changed files with 29 additions and 14 deletions

View File

@ -153,9 +153,9 @@ func aggregate(db datastore.Datastore) {
}
func collect(db datastore.Datastore, pageviews chan *models.Pageview) {
var buffer []*models.Pageview
var size = 800
var timeout = 600 * time.Millisecond
var buffer = make([]*models.Pageview, 0)
for {
select {
@ -163,12 +163,12 @@ func collect(db datastore.Datastore, pageviews chan *models.Pageview) {
buffer = append(buffer, pageview)
if len(buffer) >= size {
persist(db, buffer)
buffer = buffer[:0]
buffer = make([]*models.Pageview, 0)
}
case <-time.After(timeout):
if len(buffer) > 0 {
persist(db, buffer)
buffer = buffer[:0]
buffer = make([]*models.Pageview, 0)
}
}
}
@ -179,11 +179,11 @@ func persist(db datastore.Datastore, pageviews []*models.Pageview) {
updates := make([]*models.Pageview, 0, n)
inserts := make([]*models.Pageview, 0, n)
for _, p := range pageviews {
if !p.IsBounce {
updates = append(updates, p)
for i := range pageviews {
if !pageviews[i].IsBounce {
updates = append(updates, pageviews[i])
} else {
inserts = append(inserts, p)
inserts = append(inserts, pageviews[i])
}
}
@ -192,11 +192,11 @@ func persist(db datastore.Datastore, pageviews []*models.Pageview) {
var err error
err = db.InsertPageviews(inserts)
if err != nil {
log.Error(err)
log.Errorf("error inserting pageviews: %s", err)
}
err = db.UpdatePageviews(updates)
if err != nil {
log.Error(err)
log.Errorf("error updating pageviews: %s", err)
}
}

View File

@ -36,12 +36,27 @@ func (db *sqlstore) InsertPageviews(pageviews []*models.Pageview) error {
placeholders := strings.Repeat("(?, ?, ?, ?, ?, ?, ?, ?, ?, ?),", n)
placeholders = placeholders[:len(placeholders)-1]
// generate values slice
values := make([]interface{}, 0, n*10)
for i := 0; i < n; i++ {
values = append(values, pageviews[i].ID, pageviews[i].Hostname, pageviews[i].Pathname, pageviews[i].IsNewVisitor, pageviews[i].IsNewSession, pageviews[i].IsUnique, pageviews[i].IsBounce, pageviews[i].Referrer, pageviews[i].Duration, pageviews[i].Timestamp)
// init values slice with correct length
nValues := n * 10
values := make([]interface{}, nValues)
// overwrite nil values in slice
j := 0
for i := range pageviews {
j = i * 10
values[j] = pageviews[i].ID
values[j+1] = pageviews[i].Hostname
values[j+2] = pageviews[i].Pathname
values[j+3] = pageviews[i].IsNewVisitor
values[j+4] = pageviews[i].IsNewSession
values[j+5] = pageviews[i].IsUnique
values[j+6] = pageviews[i].IsBounce
values[j+7] = pageviews[i].Referrer
values[j+8] = pageviews[i].Duration
values[j+9] = pageviews[i].Timestamp
}
// string together query & execute with values
query := `INSERT INTO pageviews(id, hostname, pathname, is_new_visitor, is_new_session, is_unique, is_bounce, referrer, duration, timestamp) VALUES ` + placeholders
query = db.Rebind(query)
_, err := db.Exec(query, values...)
@ -69,7 +84,7 @@ func (db *sqlstore) UpdatePageviews(pageviews []*models.Pageview) error {
return err
}
for i := 0; i < len(pageviews); i++ {
for i := range pageviews {
_, err = stmt.Exec(query, pageviews[i].IsBounce, pageviews[i].Duration)
}