Skip to content

Commit aacf7cc

Browse files
committed
Reworks date parsing, formatting etc for perf
Isolates moment.js
1 parent 11eacb2 commit aacf7cc

18 files changed

+87
-42
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [5.0.1] - 2017-09-14
8+
### Added
9+
10+
### Changed
11+
- Optimizes date handling (parsing and formatting) to increase blame annotation performance and reduce memory consumption
12+
13+
### Fixed
14+
715
## [5.0.0] - 2017-09-12
816
### Added
917
- Adds an all-new `GitLens` custom view to the Explorer activity

src/annotations/annotations.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { Strings } from '../system';
1+
import { Dates, Strings } from '../system';
22
import { DecorationInstanceRenderOptions, DecorationOptions, MarkdownString, ThemableDecorationRenderOptions } from 'vscode';
33
import { DiffWithCommand, ShowQuickCommitDetailsCommand } from '../commands';
44
import { IThemeConfig, themeDefaults } from '../configuration';
55
import { GlyphChars } from '../constants';
66
import { CommitFormatter, GitCommit, GitDiffChunkLine, GitService, GitUri, ICommitFormatOptions } from '../gitService';
7-
import * as moment from 'moment';
87

98
interface IHeatmapConfig {
109
enabled: boolean;
@@ -28,13 +27,13 @@ const escapeMarkdownRegEx = /[`\>\#\*\_\-\+\.]/g;
2827

2928
export class Annotations {
3029

31-
static applyHeatmap(decoration: DecorationOptions, date: Date, now: moment.Moment) {
30+
static applyHeatmap(decoration: DecorationOptions, date: Date, now: number) {
3231
const color = this._getHeatmapColor(now, date);
3332
(decoration.renderOptions!.before! as any).borderColor = color;
3433
}
3534

36-
private static _getHeatmapColor(now: moment.Moment, date: Date) {
37-
const days = now.diff(moment(date), 'days');
35+
private static _getHeatmapColor(now: number, date: Date) {
36+
const days = Dates.dateDaysFromNow(date, now);
3837

3938
if (days <= 2) return '#ffeca7';
4039
if (days <= 7) return '#ffdd8c';
@@ -65,7 +64,7 @@ export class Annotations {
6564
message = `\n\n> ${message}`;
6665
}
6766

68-
const markdown = new MarkdownString(`[\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.sha)}) &nbsp; __${commit.author}__, ${moment(commit.date).fromNow()} &nbsp; _(${moment(commit.date).format(dateFormat)})_${message}`);
67+
const markdown = new MarkdownString(`[\`${commit.shortSha}\`](${ShowQuickCommitDetailsCommand.getMarkdownCommandArgs(commit.sha)}) &nbsp; __${commit.author}__, ${commit.fromNow()} &nbsp; _(${commit.formatDate(dateFormat)})_${message}`);
6968
markdown.isTrusted = true;
7069
return markdown;
7170
}

src/annotations/gutterBlameAnnotationProvider.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Annotations, endOfLineIndex } from './annotations';
66
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
77
import { GlyphChars } from '../constants';
88
import { GitBlameCommit, ICommitFormatOptions } from '../gitService';
9-
import * as moment from 'moment';
109

1110
export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
1211

@@ -32,7 +31,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
3231
tokenOptions: tokenOptions
3332
};
3433

35-
const now = moment();
34+
const now = Date.now();
3635
const offset = this.uri.offset;
3736
const renderOptions = Annotations.gutterRenderOptions(this._config.theme, cfg.heatmap);
3837
const dateFormat = this._config.defaultDateFormat;

src/annotations/hoverBlameAnnotationProvider.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { FileAnnotationType } from './annotationController';
44
import { Annotations, endOfLineIndex } from './annotations';
55
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
66
import { GitBlameCommit } from '../gitService';
7-
import * as moment from 'moment';
87

98
export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
109

@@ -18,7 +17,7 @@ export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
1817

1918
const cfg = this._config.annotations.file.hover;
2019

21-
const now = moment();
20+
const now = Date.now();
2221
const offset = this.uri.offset;
2322
const renderOptions = Annotations.hoverRenderOptions(this._config.theme, cfg.heatmap);
2423
const dateFormat = this._config.defaultDateFormat;

src/git/formatters/commit.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { Strings } from '../../system';
33
import { GitCommit } from '../models/commit';
44
import { Formatter, IFormatOptions } from './formatter';
5-
import * as moment from 'moment';
65
import { GlyphChars } from '../../constants';
76

87
export interface ICommitFormatOptions extends IFormatOptions {
@@ -20,7 +19,7 @@ export interface ICommitFormatOptions extends IFormatOptions {
2019
export class CommitFormatter extends Formatter<GitCommit, ICommitFormatOptions> {
2120

2221
get ago() {
23-
const ago = moment(this._item.date).fromNow();
22+
const ago = this._item.fromNow();
2423
return this._padOrTruncate(ago, this._options.tokenOptions!.ago);
2524
}
2625

@@ -30,12 +29,12 @@ export class CommitFormatter extends Formatter<GitCommit, ICommitFormatOptions>
3029
}
3130

3231
get authorAgo() {
33-
const authorAgo = `${this._item.author}, ${moment(this._item.date).fromNow()}`;
32+
const authorAgo = `${this._item.author}, ${this._item.fromNow()}`;
3433
return this._padOrTruncate(authorAgo, this._options.tokenOptions!.authorAgo);
3534
}
3635

3736
get date() {
38-
const date = moment(this._item.date).format(this._options.dateFormat!);
37+
const date = this._item.formatDate(this._options.dateFormat!);
3938
return this._padOrTruncate(date, this._options.tokenOptions!.date);
4039
}
4140

src/git/git.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ export * from './remotes/provider';
2121

2222
let git: IGit;
2323

24-
// `--format=%H -%nauthor %an%nauthor-date %ai%ncommitter %cn%ncommitter-date %ci%nparents %P%nsummary %B%nfilename ?`
25-
const defaultLogParams = [`log`, `--name-status`, `--full-history`, `-M`, `--date=iso8601`, `--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?`];
26-
const defaultStashParams = [`stash`, `list`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor-date %ai%nreflog-selector %gd%nsummary %B%nfilename ?`];
24+
const defaultBlameParams = [`blame`, `--root`, `--incremental`];
25+
const defaultLogParams = [`log`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor %an%nauthor-date %at%nparents %P%nsummary %B%nfilename ?`];
26+
const defaultStashParams = [`stash`, `list`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor-date %at%nreflog-selector %gd%nsummary %B%nfilename ?`];
2727

2828
let defaultEncoding = 'utf8';
2929
export function setDefaultEncoding(encoding: string) {
@@ -180,7 +180,7 @@ export class Git {
180180
static blame(repoPath: string | undefined, fileName: string, sha?: string, options: { ignoreWhitespace?: boolean, startLine?: number, endLine?: number } = {}) {
181181
const [file, root] = Git.splitPath(fileName, repoPath);
182182

183-
const params = [`blame`, `--root`, `--incremental`];
183+
const params = [...defaultBlameParams];
184184

185185
if (options.ignoreWhitespace) {
186186
params.push('-w');

src/git/models/commit.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
import { Strings } from '../../system';
2+
import { Dates, Strings } from '../../system';
33
import { Uri } from 'vscode';
44
import { GlyphChars } from '../../constants';
55
import { Git } from '../git';
@@ -73,6 +73,22 @@ export class GitCommit {
7373
return Uri.file(path.resolve(this.repoPath, this.originalFileName || this.fileName));
7474
}
7575

76+
private _dateFormatter?: Dates.IDateFormatter;
77+
78+
formatDate(format: string) {
79+
if (this._dateFormatter === undefined) {
80+
this._dateFormatter = Dates.toFormatter(this.date);
81+
}
82+
return this._dateFormatter.format(format);
83+
}
84+
85+
fromNow() {
86+
if (this._dateFormatter === undefined) {
87+
this._dateFormatter = Dates.toFormatter(this.date);
88+
}
89+
return this._dateFormatter.fromNow();
90+
}
91+
7692
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
7793
return GitUri.getFormattedPath(this.fileName, separator);
7894
}

src/git/parsers/blameParser.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
import { Strings } from '../../system';
33
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitCommitLine } from './../git';
4-
import * as moment from 'moment';
54
import * as path from 'path';
65

76
interface BlameEntry {
@@ -134,7 +133,7 @@ export class GitBlameParser {
134133
}
135134
}
136135

137-
commit = new GitBlameCommit(repoPath!, entry.sha, fileName!, entry.author, moment(`${entry.authorDate} ${entry.authorTimeZone}`, 'X +-HHmm').toDate(), entry.summary!, []);
136+
commit = new GitBlameCommit(repoPath!, entry.sha, fileName!, entry.author, new Date(entry.authorDate as any * 1000), entry.summary!, []);
138137

139138
if (fileName !== entry.fileName) {
140139
commit.originalFileName = entry.fileName;

src/git/parsers/logParser.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Strings } from '../../system';
33
import { Range } from 'vscode';
44
import { Git, GitAuthor, GitCommitType, GitLog, GitLogCommit, GitStatusFileStatus, IGitStatusFile } from './../git';
55
// import { Logger } from '../../logger';
6-
import * as moment from 'moment';
76
import * as path from 'path';
87

98
interface LogEntry {
@@ -87,7 +86,7 @@ export class GitLogParser {
8786
break;
8887

8988
case 'author-date':
90-
entry.authorDate = `${lineParts[1]}T${lineParts[2]}${lineParts[3]}`;
89+
entry.authorDate = lineParts[1];
9190
break;
9291

9392
case 'parents':
@@ -231,7 +230,7 @@ export class GitLogParser {
231230
}
232231
}
233232

234-
commit = new GitLogCommit(type, repoPath!, entry.sha, relativeFileName, entry.author, moment(entry.authorDate).toDate(), entry.summary!, entry.status, entry.fileStatuses, undefined, entry.originalFileName);
233+
commit = new GitLogCommit(type, repoPath!, entry.sha, relativeFileName, entry.author, new Date(entry.authorDate! as any * 1000), entry.summary!, entry.status, entry.fileStatuses, undefined, entry.originalFileName);
235234
commit.parentShas = entry.parentShas!;
236235

237236
if (relativeFileName !== entry.fileName) {

src/git/parsers/stashParser.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
import { Git, GitStash, GitStashCommit, GitStatusFileStatus, IGitStatusFile } from './../git';
33
// import { Logger } from '../../logger';
4-
import * as moment from 'moment';
54

65
interface StashEntry {
76
sha: string;
@@ -42,7 +41,7 @@ export class GitStashParser {
4241

4342
switch (lineParts[0]) {
4443
case 'author-date':
45-
entry.date = `${lineParts[1]}T${lineParts[2]}${lineParts[3]}`;
44+
entry.date = lineParts[1];
4645
break;
4746

4847
case 'summary':
@@ -120,7 +119,7 @@ export class GitStashParser {
120119

121120
let commit = commits.get(entry.sha);
122121
if (commit === undefined) {
123-
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, moment(entry.date).toDate(), entry.summary, undefined, entry.fileStatuses) as GitStashCommit;
122+
commit = new GitStashCommit(entry.stashName, repoPath, entry.sha, entry.fileNames, new Date(entry.date! as any * 1000), entry.summary, undefined, entry.fileStatuses) as GitStashCommit;
124123
commits.set(entry.sha, commit);
125124
}
126125
}

0 commit comments

Comments
 (0)