editor_render.rs

  1use criterion::{Bencher, BenchmarkId};
  2use editor::{
  3    Editor, EditorMode, MultiBuffer,
  4    actions::{DeleteToPreviousWordStart, SelectAll, SplitSelectionIntoLines},
  5};
  6use gpui::{AppContext, Focusable as _, TestAppContext, TestDispatcher};
  7use project::Project;
  8use rand::{Rng as _, SeedableRng as _, rngs::StdRng};
  9use settings::SettingsStore;
 10use ui::IntoElement;
 11use util::RandomCharIter;
 12
 13fn editor_input_with_1000_cursors(bencher: &mut Bencher<'_>, cx: &TestAppContext) {
 14    let mut cx = cx.clone();
 15    let text = String::from_iter(["line:\n"; 1000]);
 16    let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx));
 17
 18    let cx = cx.add_empty_window();
 19    let editor = cx.update(|window, cx| {
 20        let editor = cx.new(|cx| {
 21            let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx);
 22            editor.set_style(editor::EditorStyle::default(), window, cx);
 23            editor.select_all(&SelectAll, window, cx);
 24            editor.split_selection_into_lines(
 25                &SplitSelectionIntoLines {
 26                    keep_selections: true,
 27                },
 28                window,
 29                cx,
 30            );
 31            editor
 32        });
 33        window.focus(&editor.focus_handle(cx));
 34        editor
 35    });
 36
 37    bencher.iter(|| {
 38        cx.update(|window, cx| {
 39            editor.update(cx, |editor, cx| {
 40                editor.handle_input("hello world", window, cx);
 41                editor.delete_to_previous_word_start(
 42                    &DeleteToPreviousWordStart {
 43                        ignore_newlines: false,
 44                        ignore_brackets: false,
 45                    },
 46                    window,
 47                    cx,
 48                );
 49                editor.delete_to_previous_word_start(
 50                    &DeleteToPreviousWordStart {
 51                        ignore_newlines: false,
 52                        ignore_brackets: false,
 53                    },
 54                    window,
 55                    cx,
 56                );
 57            });
 58        })
 59    });
 60}
 61
 62fn open_editor_with_one_long_line(bencher: &mut Bencher<'_>, args: &(String, TestAppContext)) {
 63    let (text, cx) = args;
 64    let mut cx = cx.clone();
 65
 66    bencher.iter(|| {
 67        let buffer = cx.update(|cx| MultiBuffer::build_simple(&text, cx));
 68
 69        let cx = cx.add_empty_window();
 70        let _ = cx.update(|window, cx| {
 71            let editor = cx.new(|cx| {
 72                let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx);
 73                editor.set_style(editor::EditorStyle::default(), window, cx);
 74                editor
 75            });
 76            window.focus(&editor.focus_handle(cx));
 77            editor
 78        });
 79    });
 80}
 81
 82fn editor_render(bencher: &mut Bencher<'_>, cx: &TestAppContext) {
 83    let mut cx = cx.clone();
 84    let buffer = cx.update(|cx| {
 85        let mut rng = StdRng::seed_from_u64(1);
 86        let text_len = rng.random_range(10000..90000);
 87        if rng.random() {
 88            let text = RandomCharIter::new(&mut rng)
 89                .take(text_len)
 90                .collect::<String>();
 91            MultiBuffer::build_simple(&text, cx)
 92        } else {
 93            MultiBuffer::build_random(&mut rng, cx)
 94        }
 95    });
 96
 97    let cx = cx.add_empty_window();
 98    let editor = cx.update(|window, cx| {
 99        let editor = cx.new(|cx| {
100            let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx);
101            editor.set_style(editor::EditorStyle::default(), window, cx);
102            editor
103        });
104        window.focus(&editor.focus_handle(cx));
105        editor
106    });
107
108    bencher.iter(|| {
109        cx.update(|window, cx| {
110            // editor.update(cx, |editor, cx| editor.move_down(&MoveDown, window, cx));
111            let mut view = editor.clone().into_any_element();
112            let _ = view.request_layout(window, cx);
113            let _ = view.prepaint(window, cx);
114            view.paint(window, cx);
115        });
116    })
117}
118
119pub fn benches() {
120    let dispatcher = TestDispatcher::new(StdRng::seed_from_u64(1));
121    let cx = gpui::TestAppContext::build(dispatcher, None);
122    cx.update(|cx| {
123        let store = SettingsStore::test(cx);
124        cx.set_global(store);
125        SettingsStore::load_registered_settings(cx);
126
127        assets::Assets.load_test_fonts(cx);
128        theme::init(theme::LoadThemes::JustBase, cx);
129        // release_channel::init(SemanticVersion::default(), cx);
130        client::init_settings(cx);
131        language::init(cx);
132        workspace::init_settings(cx);
133        Project::init_settings(cx);
134        editor::init(cx);
135    });
136
137    let mut criterion: criterion::Criterion<_> =
138        (criterion::Criterion::default()).configure_from_args();
139
140    // setup app context
141    let mut group = criterion.benchmark_group("Time to render");
142    group.bench_with_input(
143        BenchmarkId::new("editor_render", "TestAppContext"),
144        &cx,
145        editor_render,
146    );
147
148    group.finish();
149
150    let text = String::from_iter(["char"; 1000]);
151    let mut group = criterion.benchmark_group("Build buffer with one long line");
152    group.bench_with_input(
153        BenchmarkId::new("editor_with_one_long_line", "(String, TestAppContext )"),
154        &(text, cx.clone()),
155        open_editor_with_one_long_line,
156    );
157
158    group.finish();
159
160    let mut group = criterion.benchmark_group("multi cursor edits");
161    group.bench_with_input(
162        BenchmarkId::new("editor_input_with_1000_cursors", "TestAppContext"),
163        &cx,
164        editor_input_with_1000_cursors,
165    );
166    group.finish();
167}
168
169fn main() {
170    benches();
171    criterion::Criterion::default()
172        .configure_from_args()
173        .final_summary();
174}