Rails性能分析故事,或者说我是如何发现Faker试图教我的应用程序学习澳大利亚俚语的
很久以前(其实是几天前),我一直在做一个小的重构任务:将其集成factory_bot到邮件预览中。
看起来是个很简单的任务:加载factory_bot_rails并包含语法方法:
# spec/mailers/previews/application_preview.rb
require "factory_bot_rails"
class ApplicationPreview < ActionMailer::Preview
include FactoryBot::Syntax::Methods
private
# user record for previews
def user
@user ||= build_stubbed :user
end
end
完成上述操作后,我检查了本地一切是否正常,并发现了一些奇怪的事情:
哇!我们居然有这么多语言版本!在我们这个只有英文版的应用程序里!太棒了!
不,其实不是。
我很快找到了它的来源:这是faker我们工厂里使用的宝石。
我查看了代码库,有点惊讶:
require 'i18n'
#...
I18n.load_path += Dir[File.join(mydir, 'locales', '**/*.yml')]
I18n.reload! if I18n.backend.initialized?
Faker 会加载所有语言环境文件,不让你选择想要的语言环境。这让我感到意外。
注意:您可以通过设置来明确指定要在应用程序中使用的区域设置config.i18n.available_locales;如果未设置,则所有已加载的区域设置都将可用。
我决定测试一下加载大量不必要的 YML 文件会对应用程序启动时间产生什么影响。
由于i18n系统会延迟加载语言环境,我已在我的代码中添加了以下行rspec_helper.rb来强制加载:
# add to rails_helper.rb
I18n.backend.load_translations
注意:由于我们faker在工厂中使用,因此几乎每次测试都需要设置区域设置。
我的软件包里已经包含了所需的test-prof组件,所以分析启动时间只需要运行这一条命令:
$ SAMPLE=1 TEST_STACK_PROF=boot TEST_STACK_PROF_FORMAT=json bundle exec rspec
让我解释一下这里发生了什么。
我们“告诉”Test Prof使用Stack Prof和启动模式来分析我们的测试运行。
在这种模式下,stackprof程序会在加载完成后立即开始收集样本,并在第一次测试运行之前(更准确地说,是在 RSpec before(:suite)hook 中)停止。
我们还传递参数SAMPLE=1,只执行一个随机测试(Test Prof 也提供了此功能):我们不在乎具体的例子,因为我们正在分析启动时间。
最后,TEST_STACK_PROF_FORMAT它用于生成 JSON 格式的分析报告(该功能已添加到stackprof自身,但尚未发布)。
如何处理这份 JSON 报告?让我们把它加载到Speedscope中!
Speedscope是一个火焰图查看器,它可以将流行的分析器(包括stackprof)生成的 JSON 报告可视化。
注意:什么是火焰图以及如何解读火焰图?请查看“官方文档”以及Miha Rekar 的演讲。
这就是我发现的:
加载语言环境耗时约 1.1 秒。
如果我们只加载英文文件(使用此补丁)会怎样?
加载语言环境仅用了约 0.4 秒。
看起来没什么大不了的😕
如果我们再加上其他条件,bootsnap就可以在不“修补”的情况下达到同样的效果faker:
也许我们浪费了很多内存?
memory_profiler让我们尝试使用gem来测量内存占用:
require "memory_profiler"
MemoryProfiler.report do
I18n.backend.load_translations
end.yield_self(&:pretty_print)
加载所有可用语言环境时:
retained objects by gem
-----------------------------------
147586 psych
5462 i18n-1.5.3
2 activesupport-6.0.0.beta1
retained objects by class
-----------------------------------
148628 String
2550 Array
1022 Symbol
848 Hash
2 Proc
还有仅限英文的版本:
retained objects by gem
-----------------------------------
44301 psych
3418 i18n-1.5.3
2 activesupport-6.0.0.beta1
retained objects by class
-----------------------------------
45240 String
1202 Array
910 Symbol
367 Hash
2 Proc
所以,2.6MB 和 7.8MB 之间的差别可以忽略不计。再说一遍。
我们必须承认,就此案而言,我们的分析并未发现任何重大问题。
这也可以算是一个圆满的结局🙂)
PS 还可以看看这些关于使用 Test Prof 进行性能分析的帖子:“Ruby 测试运行缓慢的好医生”和“Ruby 测试的工厂疗法”。
PPS:是的,Faker确实支持澳大利亚俚语。
请访问https://evilmartians.com/chronicles阅读更多开发文章!
文章来源:https://dev.to/evilmartians/rails-profiling-story-or-how-i-caught-faker-trying-to-teach-my-app-australian-slang-8ai



