{"id":228561,"date":"2021-11-24T20:59:36","date_gmt":"2021-11-25T04:59:36","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/java\/?p=228561"},"modified":"2021-11-24T21:34:15","modified_gmt":"2021-11-25T05:34:15","slug":"java-on-visual-studio-code-update-october-2021","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/java\/java-on-visual-studio-code-update-october-2021\/","title":{"rendered":"Java on Visual Studio Code Update \u2013 October 2021"},"content":{"rendered":"<p>Hi everyone, welcome to the October edition of the Visual Studio Code Java update! In this post, we are going to take a deep dive of the recent performance improvement on auto-completion.<\/p>\n<p><strong><span style=\"font-size: 18pt;\">Performance Improvement &#8211; Faster Code Completion<\/span><\/strong><\/p>\n<p>With the recent <a href=\"https:\/\/devblogs.microsoft.com\/java\/\">1.0 release of the Java Language Server,<\/a> we have made substantial improvement on the performance of auto-completion. The chart below compares the code completion response time between recent versions. For common scenarios such as completing types and constructor names, the code completion performance is improved significantly compared to previous versions (v0.80, v0.81 and v.0.82)<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-228567\" src=\"https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1.png\" alt=\"Performance Comparison\" width=\"1771\" height=\"620\" srcset=\"https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1.png 1771w, https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1-300x105.png 300w, https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1-1024x358.png 1024w, https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1-768x269.png 768w, https:\/\/devblogs.microsoft.com\/java\/wp-content\/uploads\/sites\/51\/2021\/11\/Picture1-1-1536x538.png 1536w\" sizes=\"(max-width: 1771px) 100vw, 1771px\" \/><\/a><\/p>\n<p><span style=\"font-size: 18pt;\">Overview of Improvements<\/span><\/p>\n<p><span class=\"TextRun BCX0 SCXW144494115\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun BCX0 SCXW144494115\">The completion engine consists of three phases:<\/span><\/span><\/p>\n<ul>\n<li><span class=\"TextRun BCX0 SCXW144494115\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun BCX0 SCXW144494115\">Phase 1 (P1) &#8211; Searching the indexer to find proposals<\/span><\/span><\/li>\n<li><span class=\"TextRun BCX0 SCXW144494115\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun ContextualSpellingAndGrammarErrorV2 BCX0 SCXW144494115\">Phase 2 (P2) &#8211; C<\/span><span class=\"NormalTextRun ContextualSpellingAndGrammarErrorV2 BCX0 SCXW144494115\">onverting<\/span><span class=\"NormalTextRun BCX0 SCXW144494115\"> proposals into completion items<\/span><\/span><\/li>\n<li><span class=\"TextRun BCX0 SCXW144494115\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun BCX0 SCXW144494115\">Phase 3 (P3) &#8211; Calculating code snippet proposals. <\/span><\/span><\/li>\n<\/ul>\n<p><span class=\"TextRun BCX0 SCXW144494115\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun BCX0 SCXW144494115\">Based on our analysis, we found that there was room for improvement in all three phases. The following table shows the improvements we have made in the past versions. <\/span><span class=\"NormalTextRun BCX0 SCXW144494115\">W<\/span><span class=\"NormalTextRun BCX0 SCXW144494115\">e will talk more about the details of those changes in the next section.<\/span><\/span><span class=\"EOP BCX0 SCXW144494115\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%; height: 222px;\">\n<tbody>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">0.80.0<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">0.81.0<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">0.82.0<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">1.0.0<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">Reduce I\/O on Windows<strong> (P2)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">Optimize for constants \/ default values <strong>(P2)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">Delay resolving generic snippets <strong>(P3)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">Optimize for anonymous constructors <strong>(P2)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">JDT Search Engine &#8211; Optimize unit.complete() <strong>(P1)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 28px;\"><span style=\"font-size: 10pt;\">JDT Search Engine &#8211; Improve I\/O of indexing files <strong>(P1)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 28px;\"><span style=\"font-size: 10pt;\">\u2705<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 10%; height: 26px;\"><span style=\"font-size: 10pt;\">Defer TextEdit calculation <strong>(P2)<\/strong><\/span><\/td>\n<td style=\"width: 20%; height: 26px;\"><\/td>\n<td style=\"width: 20%; height: 26px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 26px;\"><span style=\"font-size: 10pt;\">N\/A<\/span><\/td>\n<td style=\"width: 20%; height: 26px;\"><span style=\"font-size: 10pt;\">Planned<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: 24px;\">Key Changes in Recent Releases<\/span><\/p>\n<p aria-level=\"5\"><b><span data-contrast=\"none\">Version 0.81.0 &#8211; Reduce I\/O on Windows. <\/span><\/b><a href=\"https:\/\/github.com\/eclipse\/eclipse.jdt.ls\/issues\/1831\"><b><span data-contrast=\"none\">#1831<\/span><\/b><\/a><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">In past benchmarks, we found a big proportion of time cost was to calculate URI of files. It also explained our observation that completion performance was relatively worse on the Windows platform because of platform-specific filesystem related implementation in JVM. By removing unnecessary calculation of URIs, we improved the performance especially on the Windows platform.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p aria-level=\"5\"><b><span data-contrast=\"none\">Version 0.81.0 &#8211; Optimize for constants\/default values. <\/span><\/b><a href=\"https:\/\/github.com\/eclipse\/eclipse.jdt.ls\/issues\/1835\"><b><span data-contrast=\"none\">#1835<\/span><\/b><\/a><b><span data-contrast=\"none\">\u00a0<\/span><\/b><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">When we complete a constant field (e.g.\u00a0<\/span><span style=\"font-family: 'courier new', courier, monospace;\" data-contrast=\"auto\">Constants.*<\/span><span data-contrast=\"auto\">), the completion popup will show the suggested field names as well as their constant values (e.g.\u00a0<\/span><span data-contrast=\"auto\">Bit1 : int = 1<\/span><span data-contrast=\"auto\">) in the choice list. Our profiling found this is extremely slow when the class contains a large of constant field members. This is because we calculate the field value from AST Tree, which is expensive when operating on a large file.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">To\u00a0optimize it, we decide to defer resolving\u00a0the\u00a0constant value. The completion will simplify the suggestion label and only show the field name (e.g.\u00a0<\/span><span data-contrast=\"auto\">Bit1 :\u00a0int<\/span><span data-contrast=\"auto\">). And when you hover over this completion item for Javadoc, then display its constant value in the Javadoc section.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Here is\u00a0a\u00a0benchmark comparison of field completion on a class with 1400+ lines and 150+ constant fields.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 32.6106%; height: 84px;\">\n<tbody>\n<tr style=\"height: 28px;\">\n<td style=\"width: 11.3793%; height: 28px;\"><span data-contrast=\"auto\">Version<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<td style=\"width: 21.2315%; height: 28px;\"><span data-contrast=\"auto\">Average response time<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 11.3793%; height: 28px;\"><span data-contrast=\"auto\">0.80.0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<td style=\"width: 21.2315%; height: 28px;\"><span data-contrast=\"auto\">1429ms<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 11.3793%; height: 28px;\"><span data-contrast=\"auto\">0.81.0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<td style=\"width: 21.2315%; height: 28px;\"><span data-contrast=\"auto\">72ms<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><b style=\"font-size: 1rem;\"><span data-contrast=\"none\">Version 0.82.0 &#8211; Delay resolving generic snippets. <\/span><\/b><a style=\"background-color: #f7f7f9; font-size: 1rem;\" href=\"https:\/\/github.com\/eclipse\/eclipse.jdt.ls\/issues\/1838\"><b><span data-contrast=\"none\">#1838<\/span><\/b><\/a><span style=\"font-size: 1rem;\" data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">There are two types of Snippets:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"none\">Generic snippets (e.g.\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">foreach<\/span>,\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">fori<\/span>,\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">ifelse<\/span>, etc.)<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"none\">Type definition snippets (e.g.\u00a0class, interface, etc.)<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">For generic snippets, it evaluates template patterns with given context before constructing\u00a0the\u00a0`TextEdit` of a completion item. Evaluation can be expensive. Now<\/span><span data-contrast=\"none\">\u00a0we defer the evaluation to the resolving stage. When a completion snippet item is constructed, template patterns are filled in as\u00a0a\u00a0placeholder. Actual values are evaluated in\u00a0the\u00a0resolving stage which doesn\u2019t block completion items from showing. It\u2019s also an experiment on how far \u201cdelay resolving TextEdit\u201d can potentially improve the performance, and in most cases,\u00a0it should work well.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p aria-level=\"5\"><b><span data-contrast=\"none\">Version 0.82.0 &#8211; Optimize for anonymous constructors.\u00a0 <\/span><\/b><a href=\"https:\/\/github.com\/eclipse\/eclipse.jdt.ls\/issues\/1836\"><b><span data-contrast=\"none\">#1836<\/span><\/b><\/a><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">When we complete for\u00a0<\/span><span data-contrast=\"none\">new Runnable<\/span><span data-contrast=\"none\">, the expected output should be:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span style=\"font-family: 'courier new', courier, monospace;\">Runnable() {}\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">It is made up of two parts.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li><span data-contrast=\"none\">the name\u00a0<\/span><span style=\"font-family: 'courier new', courier, monospace;\">Runnable\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\">An empty <span style=\"font-family: 'courier new', courier, monospace;\">body\u00a0<\/span><\/span><span style=\"font-family: 'courier new', courier, monospace;\">() {\\n\\t\\n}\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"none\">During performance profiling, we found CodeFormatUtil.format was costing a lot of time. <\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">To have\u00a0a\u00a0correct indentation and line delimiters, they are formatted with current preferences. Formatting is expensive, and the same content (empty body) was repeatedly formatted for all items (sometimes up to thousands). To improve it, we format the empty body once and reuse it among all items.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Version 1.0.0 &#8211; Speed up the search performance of code completion.<\/span><\/b><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">There are two changes to optimize index search performance.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li><b><span data-contrast=\"none\">Make index query jobs more efficient.<\/span><\/b><span data-contrast=\"none\">\u00a0<\/span><a href=\"https:\/\/github.com\/eclipse\/eclipse.jdt.ls\/issues\/1846\"><span data-contrast=\"none\">#1846<\/span><\/a><span data-contrast=\"none\">,\u00a0<\/span><a href=\"https:\/\/bugs.eclipse.org\/bugs\/show_bug.cgi?id=575562\"><span data-contrast=\"none\">#575562<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"none\">Our performance profiling shows that 97% of\u00a0the\u00a0CPU time of the index query jobs is spent on I\/O for loading index content from disk. This is because the indexing mechanism we use tends to save memory and uses very little cache in the search engine. Almost every query must reload the index content from\u00a0the\u00a0disk. One straightforward optimization is to reduce the frequency of I\/O.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The Java indexer consists of multiple\u00a0hashtables, each used to record a certain type of code sections, such as type declarations, method declarations, references, method references, etc. A typical query job reads one or more\u00a0hashtables\u00a0from the index and then joins\u00a0these index entries into the target result.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">When we complete for the type\/constructor\u00a0name (e.g\u00a0<\/span><span style=\"font-family: 'courier new', courier, monospace;\" data-contrast=\"auto\">Str<\/span><span data-contrast=\"auto\">,\u00a0<\/span><span style=\"font-family: 'courier new', courier, monospace;\" data-contrast=\"auto\">new Str<\/span><span data-contrast=\"auto\">), the index query job reads two\u00a0hashtables, one is the\u00a0typeDecl\u00a0table to find the matched type names, the other is the\u00a0documentName\u00a0table to find the class file path that declares the corresponding types. Since our purpose is just to complete\u00a0the\u00a0type\u00a0name and auto insert its package import, the\u00a0typeDecl\u00a0table is sufficient for our requirement, and the class file path is not necessary. Our optimization is to read the\u00a0typeDecl\u00a0index table only, and it turns out reading one less index table can save a lot of I\/O costs.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li><b><span data-contrast=\"none\">Optimize the index reading.<\/span><\/b><span data-contrast=\"auto\">\u00a0<\/span><a href=\"https:\/\/bugs.eclipse.org\/bugs\/show_bug.cgi?id=574464\"><span data-contrast=\"none\">#574464<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p aria-level=\"1\"><span data-contrast=\"auto\">It comes from a community developer&#8217;s contribution to the upstream JDT project.\u00a0The Java index uses UTF-8 to encode the index characters. When loading the indexes, we\u00a0will\u00a0decode them back. Since most index characters are just ASCII characters, we optimized the decoding method to make it faster to read ASCII.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:true,&quot;134233118&quot;:true,&quot;201341983&quot;:0,&quot;335559740&quot;:240}\">\u00a0<\/span><\/p>\n<p><strong><span style=\"font-size: 18pt;\">Future Plans\u00a0<\/span><\/strong><\/p>\n<p aria-level=\"1\"><span data-contrast=\"auto\">The improvements we listed above have made the auto completion a lot faster, but we are not done. In the future, performance continues to be our top focus and we will continue to optimize the auto-completion performance. Here are some items we have planned in the next few months.<\/span><\/p>\n<ul>\n<li aria-level=\"2\"><b><span data-contrast=\"none\">Lazy\u00a0Resolve TextEdit<\/span><\/b><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">Since most language clients don\u2019t support lazy resolve text edit for the completion items, the Java language server must calculate the text edits for all completion items in the completion response. This is the cause of most expensive calculations.\u00a0 We\u2019re collaborating with the client authors to explore the support for lazy resolving text edit.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li aria-level=\"2\"><b><span data-contrast=\"none\">More\u00a0Efficient\u00a0Indexer<\/span><\/b><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">Current index data is insufficient for some code completion scenarios such as constructor. For example, the constructor completion needs to know whether the class has generic type arguments and decide whether to add a diamond &lt;&gt; to the constructor reference. The constructor index table hasn\u2019t included such type argument info, we have to resolve them from Java models, which is expensive. We\u2019re considering optimizing the index schema to include more information.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 id=\"try-it-out\" class=\"x-hidden-focus\"><strong><span class=\"x-hidden-focus\">Feedback and Suggestions<\/span><\/strong><i class=\"fabric-icon fabric-icon--Link\" aria-hidden=\"true\"><\/i><\/h3>\n<p>Please don\u2019t hesitate to try our product! Your feedback and suggestions are very important to us and will help shape our product in future. There are several ways to leave us feedback<\/p>\n<ul>\n<li>Leave your comment on this blog post<\/li>\n<li><a href=\"https:\/\/github.com\/microsoft\/vscode-java-pack\/issues\/new\/choose\" target=\"_blank\" rel=\"noopener\">Open an issue<\/a>\u00a0on our GitHub Issues page<\/li>\n<\/ul>\n<h3 id=\"try-it-out\" class=\"x-hidden-focus\"><strong>Resources<\/strong><i class=\"fabric-icon fabric-icon--Link\" aria-hidden=\"true\"><\/i><\/h3>\n<p>Here is a list of links that are helpful to learn Java on Visual Studio Code.<\/p>\n<ul>\n<li class=\"x-hidden-focus\">Learn more about\u00a0<a class=\"x-hidden-focus\" href=\"https:\/\/code.visualstudio.com\/docs\/languages\/java\" target=\"_blank\" rel=\"noopener noreferrer\">Java on Visual Studio Code<\/a>.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi everyone, welcome to the October edition of the Visual Studio Code Java update! In this post, we are going to take a deep dive of the recent performance improvement on auto-completion. Performance Improvement &#8211; Faster Code Completion With the recent 1.0 release of the Java Language Server, we have made substantial improvement on the [&hellip;]<\/p>\n","protected":false},"author":31999,"featured_media":228580,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,1,8,15],"tags":[],"class_list":["post-228561","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud","category-java","category-open-source","category-vscode"],"acf":[],"blog_post_summary":"<p>Hi everyone, welcome to the October edition of the Visual Studio Code Java update! In this post, we are going to take a deep dive of the recent performance improvement on auto-completion. Performance Improvement &#8211; Faster Code Completion With the recent 1.0 release of the Java Language Server, we have made substantial improvement on the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/posts\/228561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/users\/31999"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/comments?post=228561"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/posts\/228561\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/media\/228580"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/media?parent=228561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/categories?post=228561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/java\/wp-json\/wp\/v2\/tags?post=228561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}