Skip to content

Use an array for building up mappings in the sourcemap generator. #43785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

DanielRosenwasser
Copy link
Member

No description provided.

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Apr 23, 2021
@DanielRosenwasser
Copy link
Member Author

@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the perf test suite on this PR at 4c86404. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the abridged perf test suite on this PR at 4c86404. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..43785

Metric master 43785 Delta Best Worst
Angular - node (v14.15.1, x64)
Memory used 320,479k (± 0.00%) 320,490k (± 0.01%) +10k (+ 0.00%) 320,454k 320,544k
Parse Time 1.91s (± 0.50%) 1.90s (± 0.40%) -0.01s (- 0.58%) 1.88s 1.91s
Bind Time 0.86s (± 0.42%) 0.86s (± 0.52%) -0.00s (- 0.23%) 0.85s 0.87s
Check Time 5.10s (± 0.50%) 5.13s (± 0.56%) +0.03s (+ 0.59%) 5.06s 5.19s
Emit Time 6.26s (± 1.03%) 6.50s (± 0.71%) +0.24s (+ 3.90%) 6.42s 6.61s
Total Time 14.12s (± 0.56%) 14.38s (± 0.46%) +0.26s (+ 1.83%) 14.24s 14.53s
Compiler-Unions - node (v14.15.1, x64)
Memory used 189,097k (± 0.58%) 206,049k (± 5.65%) +16,952k (+ 8.96%) 186,819k 219,161k
Parse Time 0.80s (± 0.85%) 0.80s (± 0.77%) -0.00s (- 0.50%) 0.79s 0.82s
Bind Time 0.56s (± 0.61%) 0.55s (± 0.66%) -0.00s (- 0.54%) 0.55s 0.56s
Check Time 7.12s (± 0.68%) 7.07s (± 0.68%) -0.05s (- 0.74%) 6.99s 7.17s
Emit Time 2.50s (± 0.67%) 2.53s (± 1.57%) +0.03s (+ 1.36%) 2.48s 2.68s
Total Time 10.98s (± 0.47%) 10.95s (± 0.74%) -0.03s (- 0.25%) 10.85s 11.24s
Monaco - node (v14.15.1, x64)
Memory used 323,229k (± 0.00%) 323,236k (± 0.01%) +7k (+ 0.00%) 323,189k 323,271k
Parse Time 1.57s (± 0.87%) 1.57s (± 0.43%) +0.00s (+ 0.13%) 1.56s 1.59s
Bind Time 0.75s (± 0.89%) 0.74s (± 0.64%) -0.01s (- 0.93%) 0.73s 0.75s
Check Time 5.12s (± 0.35%) 5.11s (± 0.51%) -0.01s (- 0.23%) 5.07s 5.18s
Emit Time 3.13s (± 0.64%) 3.12s (± 0.52%) -0.01s (- 0.48%) 3.09s 3.16s
Total Time 10.58s (± 0.23%) 10.54s (± 0.32%) -0.04s (- 0.33%) 10.48s 10.63s
TFS - node (v14.15.1, x64)
Memory used 287,662k (± 0.01%) 287,668k (± 0.00%) +6k (+ 0.00%) 287,638k 287,700k
Parse Time 1.27s (± 1.64%) 1.28s (± 1.08%) +0.00s (+ 0.39%) 1.26s 1.32s
Bind Time 0.72s (± 0.72%) 0.71s (± 0.52%) -0.00s (- 0.56%) 0.71s 0.72s
Check Time 4.71s (± 0.54%) 4.72s (± 0.56%) +0.00s (+ 0.04%) 4.67s 4.76s
Emit Time 3.32s (± 0.61%) 3.30s (± 0.71%) -0.02s (- 0.66%) 3.26s 3.35s
Total Time 10.02s (± 0.40%) 10.00s (± 0.49%) -0.02s (- 0.23%) 9.91s 10.09s
material-ui - node (v14.15.1, x64)
Memory used 440,801k (± 0.07%) 440,939k (± 0.00%) +138k (+ 0.03%) 440,877k 440,979k
Parse Time 2.00s (± 0.75%) 1.99s (± 0.83%) -0.01s (- 0.60%) 1.96s 2.03s
Bind Time 0.70s (± 0.70%) 0.70s (± 0.74%) -0.00s (- 0.71%) 0.69s 0.71s
Check Time 13.25s (± 0.81%) 13.07s (± 0.36%) -0.19s (- 1.43%) 12.97s 13.19s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.96s (± 0.66%) 15.75s (± 0.28%) -0.21s (- 1.29%) 15.66s 15.84s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-206-generic
Architecturex64
Available Memory16 GB
Available Memory8 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v14.15.1, x64)
Benchmark Name Iterations
Current 43785 10
Baseline master 10

Developer Information:

Download Benchmark

@DanielRosenwasser
Copy link
Member Author

@typescript-bot perf test this
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the perf test suite on this PR at 312ce16. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 312ce16. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..43785

Metric master 43785 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 344,232k (± 0.02%) 344,141k (± 0.02%) -92k (- 0.03%) 343,997k 344,374k
Parse Time 1.91s (± 0.66%) 1.92s (± 0.73%) +0.01s (+ 0.47%) 1.90s 1.96s
Bind Time 0.84s (± 0.62%) 0.84s (± 0.86%) +0.00s (+ 0.36%) 0.83s 0.86s
Check Time 5.24s (± 0.51%) 5.24s (± 0.53%) +0.00s (+ 0.06%) 5.18s 5.30s
Emit Time 5.90s (± 0.54%) 6.02s (± 0.98%) +0.11s (+ 1.88%) 5.90s 6.21s
Total Time 13.89s (± 0.36%) 14.02s (± 0.52%) +0.13s (+ 0.91%) 13.91s 14.20s
Compiler-Unions - node (v10.16.3, x64)
Memory used 200,706k (± 0.11%) 200,740k (± 0.02%) +35k (+ 0.02%) 200,641k 200,842k
Parse Time 0.79s (± 0.71%) 0.79s (± 1.09%) +0.00s (+ 0.51%) 0.78s 0.82s
Bind Time 0.53s (± 1.67%) 0.53s (± 1.40%) +0.00s (+ 0.57%) 0.51s 0.54s
Check Time 7.50s (± 0.70%) 7.57s (± 0.63%) +0.06s (+ 0.87%) 7.45s 7.66s
Emit Time 2.53s (± 0.49%) 2.47s (± 0.79%) -0.06s (- 2.41%) 2.43s 2.51s
Total Time 11.34s (± 0.48%) 11.36s (± 0.52%) +0.02s (+ 0.13%) 11.25s 11.51s
Monaco - node (v10.16.3, x64)
Memory used 341,719k (± 0.01%) 341,798k (± 0.03%) +80k (+ 0.02%) 341,630k 342,047k
Parse Time 1.57s (± 0.60%) 1.56s (± 0.57%) -0.00s (- 0.19%) 1.54s 1.58s
Bind Time 0.74s (± 0.88%) 0.75s (± 1.09%) +0.01s (+ 1.22%) 0.74s 0.77s
Check Time 5.32s (± 0.62%) 5.33s (± 0.88%) +0.01s (+ 0.11%) 5.22s 5.41s
Emit Time 3.02s (± 0.63%) 3.03s (± 0.91%) +0.01s (+ 0.17%) 2.98s 3.12s
Total Time 10.65s (± 0.51%) 10.67s (± 0.55%) +0.02s (+ 0.16%) 10.50s 10.78s
TFS - node (v10.16.3, x64)
Memory used 304,192k (± 0.02%) 304,199k (± 0.02%) +7k (+ 0.00%) 304,047k 304,328k
Parse Time 1.22s (± 0.37%) 1.22s (± 0.85%) -0.00s (- 0.00%) 1.20s 1.25s
Bind Time 0.71s (± 0.73%) 0.71s (± 0.48%) -0.00s (- 0.28%) 0.70s 0.71s
Check Time 4.79s (± 0.48%) 4.79s (± 0.48%) -0.01s (- 0.15%) 4.76s 4.85s
Emit Time 3.19s (± 1.39%) 3.23s (± 0.95%) +0.04s (+ 1.22%) 3.17s 3.31s
Total Time 9.91s (± 0.42%) 9.94s (± 0.40%) +0.03s (+ 0.34%) 9.87s 10.06s
material-ui - node (v10.16.3, x64)
Memory used 464,841k (± 0.01%) 464,942k (± 0.02%) +101k (+ 0.02%) 464,708k 465,109k
Parse Time 1.94s (± 0.46%) 1.96s (± 0.57%) +0.02s (+ 1.09%) 1.93s 1.98s
Bind Time 0.66s (± 0.91%) 0.65s (± 0.99%) -0.00s (- 0.46%) 0.64s 0.66s
Check Time 14.43s (± 0.94%) 14.39s (± 0.67%) -0.04s (- 0.28%) 14.20s 14.63s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 17.02s (± 0.80%) 16.99s (± 0.53%) -0.02s (- 0.14%) 16.84s 17.22s
Angular - node (v12.1.0, x64)
Memory used 321,856k (± 0.03%) 321,810k (± 0.03%) -46k (- 0.01%) 321,625k 322,087k
Parse Time 1.91s (± 0.71%) 1.92s (± 0.85%) +0.01s (+ 0.63%) 1.89s 1.96s
Bind Time 0.83s (± 0.85%) 0.83s (± 0.67%) -0.00s (- 0.12%) 0.82s 0.84s
Check Time 5.11s (± 0.53%) 5.12s (± 0.53%) +0.01s (+ 0.27%) 5.07s 5.21s
Emit Time 6.15s (± 0.79%) 6.23s (± 0.56%) +0.09s (+ 1.40%) 6.17s 6.30s
Total Time 13.99s (± 0.46%) 14.10s (± 0.49%) +0.11s (+ 0.79%) 13.99s 14.30s
Compiler-Unions - node (v12.1.0, x64)
Memory used 188,014k (± 0.44%) 187,597k (± 0.14%) -417k (- 0.22%) 186,644k 187,953k
Parse Time 0.77s (± 0.72%) 0.78s (± 1.13%) +0.01s (+ 1.04%) 0.77s 0.81s
Bind Time 0.53s (± 0.90%) 0.53s (± 0.89%) +0.00s (+ 0.57%) 0.52s 0.54s
Check Time 6.98s (± 0.52%) 7.03s (± 0.49%) +0.05s (+ 0.77%) 6.96s 7.10s
Emit Time 2.50s (± 0.99%) 2.53s (± 0.77%) +0.03s (+ 1.24%) 2.48s 2.58s
Total Time 10.78s (± 0.40%) 10.88s (± 0.32%) +0.10s (+ 0.90%) 10.81s 10.98s
Monaco - node (v12.1.0, x64)
Memory used 324,197k (± 0.02%) 324,156k (± 0.01%) -41k (- 0.01%) 324,058k 324,269k
Parse Time 1.54s (± 0.68%) 1.54s (± 0.82%) -0.00s (- 0.32%) 1.51s 1.57s
Bind Time 0.72s (± 0.83%) 0.72s (± 0.47%) -0.00s (- 0.28%) 0.72s 0.73s
Check Time 5.15s (± 0.36%) 5.14s (± 0.44%) -0.00s (- 0.08%) 5.10s 5.20s
Emit Time 3.08s (± 1.55%) 3.07s (± 0.85%) -0.02s (- 0.52%) 3.01s 3.13s
Total Time 10.49s (± 0.43%) 10.47s (± 0.41%) -0.02s (- 0.23%) 10.39s 10.59s
TFS - node (v12.1.0, x64)
Memory used 288,659k (± 0.02%) 288,673k (± 0.01%) +14k (+ 0.00%) 288,583k 288,779k
Parse Time 1.21s (± 0.55%) 1.21s (± 0.66%) -0.00s (- 0.17%) 1.19s 1.23s
Bind Time 0.70s (± 0.53%) 0.69s (± 0.83%) -0.01s (- 0.72%) 0.68s 0.70s
Check Time 4.70s (± 0.48%) 4.69s (± 0.52%) -0.01s (- 0.15%) 4.65s 4.75s
Emit Time 3.19s (± 0.86%) 3.19s (± 0.87%) -0.00s (- 0.03%) 3.09s 3.23s
Total Time 9.79s (± 0.34%) 9.78s (± 0.52%) -0.02s (- 0.17%) 9.64s 9.87s
material-ui - node (v12.1.0, x64)
Memory used 442,773k (± 0.05%) 442,633k (± 0.07%) -140k (- 0.03%) 441,724k 442,958k
Parse Time 1.95s (± 0.58%) 1.96s (± 0.57%) +0.00s (+ 0.21%) 1.93s 1.98s
Bind Time 0.65s (± 0.53%) 0.65s (± 1.19%) +0.00s (+ 0.31%) 0.64s 0.67s
Check Time 13.02s (± 0.75%) 13.13s (± 1.18%) +0.11s (+ 0.86%) 12.84s 13.51s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.62s (± 0.64%) 15.74s (± 1.02%) +0.11s (+ 0.73%) 15.43s 16.12s
Angular - node (v14.15.1, x64)
Memory used 320,479k (± 0.00%) 320,386k (± 0.08%) -93k (- 0.03%) 319,383k 320,542k
Parse Time 1.91s (± 0.50%) 1.91s (± 0.89%) +0.01s (+ 0.47%) 1.89s 1.96s
Bind Time 0.86s (± 0.42%) 0.86s (± 0.96%) 0.00s ( 0.00%) 0.85s 0.89s
Check Time 5.10s (± 0.50%) 5.11s (± 0.77%) +0.02s (+ 0.33%) 5.04s 5.21s
Emit Time 6.26s (± 1.03%) 6.39s (± 0.99%) +0.14s (+ 2.17%) 6.30s 6.62s
Total Time 14.12s (± 0.56%) 14.28s (± 0.78%) +0.16s (+ 1.15%) 14.14s 14.65s
Compiler-Unions - node (v14.15.1, x64)
Memory used 189,097k (± 0.58%) 211,099k (± 4.26%) +22,002k (+11.64%) 186,876k 217,175k
Parse Time 0.80s (± 0.85%) 0.81s (± 0.74%) +0.00s (+ 0.12%) 0.80s 0.82s
Bind Time 0.56s (± 0.61%) 0.56s (± 0.80%) +0.00s (+ 0.18%) 0.55s 0.57s
Check Time 7.12s (± 0.68%) 7.10s (± 0.47%) -0.02s (- 0.22%) 7.03s 7.20s
Emit Time 2.50s (± 0.67%) 2.44s (± 0.71%) -0.05s (- 2.12%) 2.39s 2.48s
Total Time 10.98s (± 0.47%) 10.91s (± 0.36%) -0.07s (- 0.65%) 10.83s 11.01s
Monaco - node (v14.15.1, x64)
Memory used 323,229k (± 0.00%) 323,241k (± 0.01%) +12k (+ 0.00%) 323,206k 323,293k
Parse Time 1.57s (± 0.87%) 1.57s (± 0.37%) -0.00s (- 0.13%) 1.56s 1.58s
Bind Time 0.75s (± 0.89%) 0.75s (± 0.74%) +0.00s (+ 0.27%) 0.74s 0.77s
Check Time 5.12s (± 0.35%) 5.14s (± 0.45%) +0.02s (+ 0.39%) 5.09s 5.20s
Emit Time 3.13s (± 0.64%) 3.14s (± 0.70%) +0.00s (+ 0.06%) 3.08s 3.17s
Total Time 10.58s (± 0.23%) 10.60s (± 0.41%) +0.02s (+ 0.19%) 10.49s 10.68s
TFS - node (v14.15.1, x64)
Memory used 287,662k (± 0.01%) 287,671k (± 0.00%) +9k (+ 0.00%) 287,633k 287,694k
Parse Time 1.27s (± 1.64%) 1.27s (± 0.80%) -0.00s (- 0.00%) 1.25s 1.30s
Bind Time 0.72s (± 0.72%) 0.71s (± 0.70%) -0.00s (- 0.56%) 0.71s 0.73s
Check Time 4.71s (± 0.54%) 4.72s (± 0.40%) +0.01s (+ 0.19%) 4.68s 4.76s
Emit Time 3.32s (± 0.61%) 3.29s (± 0.35%) -0.02s (- 0.66%) 3.28s 3.32s
Total Time 10.02s (± 0.40%) 10.01s (± 0.20%) -0.02s (- 0.17%) 9.97s 10.06s
material-ui - node (v14.15.1, x64)
Memory used 440,801k (± 0.07%) 440,949k (± 0.01%) +148k (+ 0.03%) 440,866k 440,995k
Parse Time 2.00s (± 0.75%) 1.99s (± 0.40%) -0.01s (- 0.65%) 1.97s 2.00s
Bind Time 0.70s (± 0.70%) 0.70s (± 0.82%) -0.00s (- 0.57%) 0.69s 0.71s
Check Time 13.25s (± 0.81%) 13.13s (± 0.69%) -0.12s (- 0.94%) 12.98s 13.42s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.96s (± 0.66%) 15.82s (± 0.57%) -0.14s (- 0.89%) 15.68s 16.12s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-206-generic
Architecturex64
Available Memory16 GB
Available Memory8 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v14.15.1, x64)
Benchmark Name Iterations
Current 43785 10
Baseline master 10

Developer Information:

Download Benchmark

@DanielRosenwasser
Copy link
Member Author

@typescript-bot perf test this
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the perf test suite on this PR at 799bbbe. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 23, 2021

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 799bbbe. You can monitor the build here.

lastNameIndex = pendingNameIndex;
}
}

mappings = mappingSegmentsBuffer.join("");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In local experimentation, I've found that I can get about a 40% speed up by batching the char code conversion:

function base64VLQFormatEncode2(value) {
  if (value < 0) {
      value = ((-value) << 1) + 1;
  }
  else {
      value = value << 1;
  }

  // Encode 5 bits at a time starting from least significant bits
  const result = [];
  do {
      let currentDigit = value & 31; // 11111
      value = value >> 5;
      if (value > 0) {
          // There are still more digits to decode, set the msb (6th bit)
          currentDigit = currentDigit | 32;
      }
      result.push(base64FormatEncode(currentDigit));
  } while (value > 0);

  return result;
}

function buildMappingStr() {
  const charCodes = [];
  // Mock representation of adding a segment, for benchmarking
  for (let i = 0; i < target; i ++) {
    charCodes.push(...base64VLQFormatEncode2(i));
  }
  let str = '';
  const segmentLength = 4096;
  for (let i = 0, len = charCodes.length; i < len; i += segmentLength) {
    const segment = String.fromCharCode.apply(null, charCodes.slice(i, i + segmentLength));
    str += segment;
  }
  return str;
}

Copy link
Contributor

@dmichon-msft dmichon-msft May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are encoding a very large number of mappings (>100000), it gets faster to use an encoder with its own buffer:

class SourceMapEncoder {
  constructor() {
    this._encoded = '';
    this._buffer = new Uint8Array(1024);
    this._bufferPos = 0;
  }

  get encoded() {
    if (this._bufferPos > 0) {
      this._commit(); 
    }
    return this._encoded;
  }

  /**
   * @param {number} code
   */
  appendCharCode(code) {
    this._buffer[this._bufferPos] = code;
    this._bufferPos++;
    
    if (this._bufferPos === this._buffer.length) {
      this._commit();
    }
  }

  /**
   * @param {number} value
   */
  appendBase64VLQ(value) {
    if (value < 0) {
        value = ((-value) << 1) + 1;
    }
    else {
        value = value << 1;
    }
  
    // Encode 5 bits at a time starting from least significant bits
    do {
        let currentDigit = value & 31; // 11111
        value = value >> 5;
        if (value > 0) {
            // There are still more digits to decode, set the msb (6th bit)
            currentDigit = currentDigit | 32;
        }
        this.appendCharCode(formatArr[currentDigit]);
    } while (value > 0);
  }

  reset() {
    this._encoded = '';
    this._bufferPos = 0;
  }

  _commit() {
    this._encoded += String.fromCharCode.apply(null, this._buffer.slice(0, this._bufferPos));
    this._bufferPos = 0;
  }
}

Call .appendBase64VLQ(value) for each mapping to append, then retrieve .encoded at the end.
Still trying to figure out why the overhead is so much higher for small counts

Copy link
Member Author

@DanielRosenwasser DanielRosenwasser May 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually tried something in the same spirit with a Uint8Array - check out #43987

@sandersn
Copy link
Member

To help with PR housekeeping, I'm going to close this draft PR. It is pretty old now.

@sandersn sandersn closed this May 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants