Optimise upload path calls

String#underscore isn't particularly slow, but it's possible for us to
call it many times in a users autocomplete request, with mostly-static
values ('User', 'Group', etc.). We can memoise this and save a
surprising amount of time (around 10% of the total request time in some
cases).
This commit is contained in:
Sean McGivern 2019-05-11 07:06:44 -05:00
parent 513fa60310
commit 79dd92c818
10 changed files with 23 additions and 7 deletions

View file

@ -45,7 +45,7 @@ class UploadsController < ApplicationController
when Appearance
true
else
permission = "read_#{model.class.to_s.underscore}".to_sym
permission = "read_#{model.class.underscore}".to_sym
can?(current_user, permission, model)
end

View file

@ -41,4 +41,8 @@ class ApplicationRecord < ActiveRecord::Base
find_or_create_by(*args)
end
end
def self.underscore
Gitlab::SafeRequestStore.fetch("model:#{self}:underscore") { self.to_s.underscore }
end
end

View file

@ -9,6 +9,6 @@ class AttachmentUploader < GitlabUploader
private
def dynamic_segment
File.join(model.class.to_s.underscore, mounted_as.to_s, model.id.to_s)
File.join(model.class.underscore, mounted_as.to_s, model.id.to_s)
end
end

View file

@ -25,6 +25,6 @@ class AvatarUploader < GitlabUploader
private
def dynamic_segment
File.join(model.class.to_s.underscore, mounted_as.to_s, model.id.to_s)
File.join(model.class.underscore, mounted_as.to_s, model.id.to_s)
end
end

View file

@ -20,7 +20,7 @@ class PersonalFileUploader < FileUploader
def self.model_path_segment(model)
return 'temp/' unless model
File.join(model.class.to_s.underscore, model.id.to_s)
File.join(model.class.underscore, model.id.to_s)
end
def object_store

View file

@ -0,0 +1,5 @@
---
title: Improve performance of users autocomplete when there are lots of results
merge_request:
author:
type: performance

View file

@ -1,3 +1,4 @@
# coding: utf-8
# frozen_string_literal: true
require 'spec_helper'
@ -13,7 +14,7 @@ describe SendFileUpload do
# user/:id
def dynamic_segment
File.join(model.class.to_s.underscore, model.id.to_s)
File.join(model.class.underscore, model.id.to_s)
end
end
end

View file

@ -13,7 +13,7 @@ FactoryBot.define do
end
# this needs to comply with RecordsUpload::Concern#upload_path
path { File.join("uploads/-/system", model.class.to_s.underscore, mount_point.to_s, 'avatar.jpg') }
path { File.join("uploads/-/system", model.class.underscore, mount_point.to_s, 'avatar.jpg') }
trait :personal_snippet_upload do
uploader "PersonalFileUploader"

View file

@ -52,4 +52,10 @@ describe ApplicationRecord do
expect { Suggestion.find_or_create_by!(note: nil) }.to raise_error(ActiveRecord::RecordInvalid)
end
end
describe '.underscore' do
it 'returns the underscored value of the class as a string' do
expect(MergeRequest.underscore).to eq('merge_request')
end
end
end

View file

@ -12,7 +12,7 @@ class Implementation < GitlabUploader
# user/:id
def dynamic_segment
File.join(model.class.to_s.underscore, model.id.to_s)
File.join(model.class.underscore, model.id.to_s)
end
end