Rails lädt einen JSON-Schema-Cache bei 944 Tabellen 22x schneller als YAML
Das Rails-Wochenprotokoll enthält zwei Einträge, die etwas bringen. Active Record kann seinen Schema-Cache jetzt als JSON schreiben und lesen: Zeigt schema_cache_path auf eine Datei mit der Endung .json, wird weder YAML noch Marshal verwendet. Bei einer Produktivanwendung mit 944 Tabellen lädt JSON laut Rails-Beitrag rund 22x schneller als YAML.
Der zweite ist bin/rails herb:check — ein Rake-Task, der jedes HTML+ERB-Template über Herb kompiliert und dabei dieselben Resolver benutzt wie das Laufzeit-Lookup, also inklusive Varianten, Locales und Engine-View-Pfaden. Abgelehnte Templates werden mit Pfad und Fehler aufgelistet, und der Task endet mit einem Fehlercode, sobald eines scheitert.

Was das bedeutet
Der Schema-Cache ist eine Startzeit-Zahl und damit eine Deploy-Zahl: bei jedem Prozessstart, jedem Container, jedem Autoscaling-Ereignis. Wer Hunderte Tabellen hat und schon einmal einem Rolling Deploy beim Kriechen zugesehen hat, bekommt hier eine Konfigurationszeile mit gemessenem Effekt — gemessen allerdings bei denen, also vor dem Zitieren selbst nachmessen.
herb:check ist aus einem anderen Grund wichtig: Ein Template-Fehler ist der klassische Fehler, den Unit-Tests nicht finden und die Produktion schon. Der Fehlercode heißt: Das gehört in die CI, nicht in ein Entwickler-Terminal. Neben den Linter gestellt, verwandelt es eine ganze Fehlerklasse in einen roten Build.
Woher die 22x tatsächlich kommen
YAML ist ein Allzweckformat mit Ankern, Aliassen, eigenen Tags und Typumwandlung — ein Parser muss das alles in Betracht ziehen. JSON hat sechs Werttypen und keine Erweiterungspunkte, und jede Laufzeitumgebung bringt einen Parser mit, der seit einem Jahrzehnt optimiert wird. Der Schema-Cache ist eine große, langweilig regelmäßige Datenstruktur — genau die Form, in der dieser Unterschied aufhört, akademisch zu sein.
Marshal ist noch schneller und zugleich versionsgebunden: Ein von einer Ruby-Version geschriebener Cache ist für eine andere nicht vertrauenswürdig. JSON hebt diese Einschränkung auf, und deshalb ist die Änderung für Container interessant, wo Image und Laufzeit nicht am selben Tag aktualisiert werden.
Was vor dem Umstellen zu messen ist. Einmal kalt rails runner "ActiveRecord::Base.connection.schema_cache" stoppen, auf einem Image mit vorhandenem Cache, und danach dasselbe mit schema_cache_path auf einer .json-Datei. Bei vierzig Tabellen wird der Unterschied unsichtbar sein; die Zahl aus der Ankündigung stammt von 944 Tabellen, und der Gewinn skaliert mit der Größe des Schemas, nicht mit dem Verkehr.