realm / realm/SwiftLint

Glob.resolveGlob() is veeeery sloooow

Open
#5,501 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Swift
Stars
19.7k
Forks
2.3k
Avg merge
1d 1h
Merged PRs (30d)
11

Description

New Issue Checklist
Describe the bug

A clear and concise description of what the bug is.

swiftlint became very slow in the last release. As if someone implemented a O(n^2) in Glob.resolveGlob(). In our project we are from several seconds (a dozen or so) to around of half an hour.

Complete output when running SwiftLint, including the stack trace and command used
$ swiftlint lint
Environment
  • SwiftLint version (run swiftlint version to be sure)?
    % swiftlint version
    0.53.0

  • Installation method used (Homebrew, CocoaPods, building from source, etc)?
    Homebrew

  • Paste your configuration file:

# insert yaml contents here
disabled_rules:
  - line_length
  - identifier_name
  - cyclomatic_complexity
  - large_tuple
  - function_body_length
  - todo
  - class_delegate_protocol
  - implicit_getter
  - orphaned_doc_comment
  - closure_parameter_position
  - void_function_in_ternary
  - for_where
  - type_body_length
  - nsobject_prefer_isequal
opt_in_rules:
  - empty_count
  - implicit_return
  - empty_string
  - empty_collection_literal
  - first_where
  - modifier_order
  - toggle_bool
  - convenience_type
#  - implicitly_unwrapped_optional
#  - force_unwrapping
#  - unavailable_function
#  - function_default_parameter_at_end
excluded: # paths to ignore during linting. Takes precedence over `included`.
  - Build
  - Danger
  - Scripts
  - "**/*Test*"
  - "Packages/Dealer/**/Mocks.generated.swift"
  - Mobile/Libraries
  - "**/.build/**"

# relax all those (we could/should tighten those later on)
# line_length: 110
file_length: 1000
type_name:
  min_length: 4
  max_length: 55
function_parameter_count: 8

custom_rules:
  no_singleton_variable:
    include: ".*\\.swift"
    exclude: ".*Test.*\\.swift"
    name: "No singleton variable"
    regex: "^[ \\t]+(?:(if )|(private (?!func ))|(let )|(var )|(weak )|(unowned )|(@(IB\\w+) ))([^=:]+(: ?\\w+)?) ?= ?[\\w.]+(shared|singelton|sharedInstance).+$"
    message: "Please inject singletons into classes or methods. This helps to make the testing easier and don't hide the dependency."
    severity: warning

  private_iboutlet_variable:
    include: ".*\\.swift"
    exclude: ".*Test.*\\.swift"
    name: "IBOutlet definitions should be private or fileprivate to avoid side effects from modifiing them outside of their container."
    regex: "^[ \\t]+@IBOutlet +(weak +)?var +[a-zA-Z0-9]+ *: *[a-zA-Z0-9]+(\\!|\\?)$"
    message: "Please use UI detached properties for assigning values to the final UI element within this class."
    severity: warning

  no_empty_line_before_closing_brace:
    include: ".*\\.swift"
    exclude: ".*Test.*\\.swift"
    name: "For readability, please avoid having an empty line before a brace."
    regex: '(\n[ \t]?\n)+[ \t]?\}'
    message: "Remove the empty line in front of the closing brace."
    severity: warning

  empty_line_after_closing_brace:
    include: ".*\\.swift"
    exclude: ".*Test.*\\.swift"
    name: "For readability, please have an empty line after a brace before a new code line starts."
    regex: '\}[ \t]?\n[ \t]?[a-zA-Z]'
    message: "Add an empty line in after the closing brace."
    severity: warning

  #no_empty_string_after_nil_coalescing:
  #  include: ".*\\.swift"
  #  excluded:
  #    - ".*Test.*\\.swift"
  #    - "Packages/Dealer"
  #    - "Packages/Consumer/Features/UserConsent"
  #  name: "Prefer using unwrapOrBlank over using empty string with nil coalescing operator"
  #  regex: '\?\? ""'
  #  message: "Please use unwrapOrBlank."
  #  severity: warning

  dead_function:
    include: ".*\\.swift"
    exclude: ".*Test.*\\.swift"
    name: "Dead code"
    regex: 'func [^\n]*\{\n(\s*super\.[^\n]*\n(\s*\/\/[^\n]*\n)*|(\s*\/\/[^\n]*\n)+)\s*\}'
    message: "Delete auto-generated functions, functions calling just super or commented functions you don't use"
    severity: warning

  final_class:
    included: ".*.swift"
    name: "Final class requirement"
    regex: "^(class |@objc class |public class |internal class |private class)"
    message: "All classes must be final or non-final. If you completely sure your class if non-final, please mark it as /* @non-final */ class"
    severity: warning

  print_usage:
    included: ".*.swift"
    name: "Print usage"
    regex: '(^print| print)+\('
    message: "Please prefer os_log for logging or debugPrint if you don't need this log in production"
    severity: warning

  objc_members_usage:
    included: ".*.swift"
    name: "objcMembers usage"
    regex: 'objcMembers'
    message: "Do not use @objcMembers. It creates unnecessary amounts of code and makes removing @objc step by step impossible"
    severity: error

  use_size_class:
    included: ".*.swift"
    name: "Use size classes"
    regex: '(UIDevice[. ]isP(hone|ad)|userInterfaceIdiom == \.p(ad|hone))'
    message: "Make use of device size classes instead of device characteristics."
    severity: error
  • Are you using nested configurations?
    If so, paste their relative paths and respective contents.
  • Which Xcode version are you using (check xcodebuild -version)?
    Xcode 15.2
    Build version 15C500b
  • Do you have a sample that shows the issue? Run echo "[string here]" | swiftlint lint --no-cache --use-stdin --enable-all-rules
    to quickly test if your example is really demonstrating the issue. If your example is more
    complex, you can use swiftlint lint --path [file here] --no-cache --enable-all-rules.
    See Instruments image
Bildschirmfoto 2024-03-20 um 16 40 52

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at Glob.resolveGlob() and profile the swiftlint lint command with the reported configuration, comparing the current runtime with the previous release. Use the linked Instruments image as context for the suspected slowdown. Done means the severe performance regression is identified and resolved without changing linting behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
performance, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.