Skip to content

Commit a4cd7d5

Browse files
authored
perf(benchmarks): add a fs-text benchmark (#27004)
1 parent 1509aa6 commit a4cd7d5

File tree

15 files changed

+584
-0
lines changed

15 files changed

+584
-0
lines changed

benchmarks/gabe-fs-text/.gitignore

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (http://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# Typescript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# dotenv environment variable files
55+
.env*
56+
57+
# gatsby files
58+
.cache/
59+
public
60+
61+
# Mac files
62+
.DS_Store
63+
64+
# Yarn
65+
yarn-error.log
66+
.pnp/
67+
.pnp.js
68+
# Yarn Integrity file
69+
.yarn-integrity
70+
71+
generated_articles
72+
yarn.lock

benchmarks/gabe-fs-text/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Gatsbyjs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

benchmarks/gabe-fs-text/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Markdown Benchmark; fs+text version
2+
3+
This is a baseline benchmark for tracking plaintext performance with individual files in the Gabe project.
4+
5+
This will produce the same site as `gabe-fs-markdown` without using any markdown.
6+
7+
The site can generate an arbitrary amount of super simple pages. Each page has a small header, a quote, and two small paragraphs of random text. No images, because that's a fixed cost we're not interested in.
8+
9+
## Install
10+
11+
Run `yarn` or `npm install`
12+
13+
## Usage
14+
15+
You can start a benchmark run like this:
16+
17+
```shell
18+
N=1000 M=2 yarn bench
19+
```
20+
21+
- `N=1000`: instructs the run to build a site of 1000 pages
22+
- `M=2`: instructs nodejs to use up to 2gb of memory for its long term storage
23+
- Deletes generates files from previous run
24+
- Generates `N` pages with pseudo-random content
25+
- Runs `gatsby clean`
26+
- Runs `gatsby build`
27+
28+
The default `yarn bench` will build 512 pages with 1gb memory.

benchmarks/gabe-fs-text/gatsby-browser.js

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
siteMetadata: {
3+
title: `Gatsby FS Text Benchmark for Gabe`,
4+
description: "A blog like no other blog",
5+
author: "Bob the Blogger",
6+
},
7+
plugins: [
8+
{
9+
resolve: `gatsby-source-filesystem`,
10+
options: {
11+
name: `blog`,
12+
path: `${__dirname}/generated_articles`,
13+
},
14+
},
15+
],
16+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const fs = require("fs")
2+
const path = require(`path`)
3+
const { createFilePath } = require(`gatsby-source-filesystem`)
4+
5+
exports.createPages = async ({ graphql, actions }) => {
6+
const { createPage } = actions
7+
const blogPost = path.resolve(`./src/templates/blog-post.js`)
8+
const result = await graphql(
9+
`
10+
{
11+
allTexto(sort: { fields: date, order: ASC }) {
12+
edges {
13+
node {
14+
id
15+
slug
16+
}
17+
}
18+
}
19+
}
20+
`
21+
)
22+
23+
if (result.errors) {
24+
throw result.errors
25+
}
26+
27+
// Create blog posts pages.
28+
const posts = result.data.allTexto.edges
29+
30+
posts.forEach(({ node }, index) => {
31+
const previous = index === posts.length - 1 ? null : posts[index + 1].node
32+
const next = index === 0 ? null : posts[index - 1].node
33+
34+
createPage({
35+
path: node.slug,
36+
component: blogPost,
37+
context: {
38+
id: node.id,
39+
slug: node.slug,
40+
previous,
41+
next,
42+
},
43+
})
44+
})
45+
}
46+
47+
exports.onCreateNode = ({ node, actions }) => {
48+
if (node.internal.type === "File") {
49+
// Do minimal processing to get some key pieces. This could be gatsby-transformer-text or -html :p
50+
51+
const html = fs.readFileSync(node.absolutePath, "utf8")
52+
53+
const base = path.basename(node.absolutePath)
54+
const slug = base.slice(11, -5) // remove date prefix and `..txt` tail
55+
const date = base.slice(0, 10)
56+
57+
const offset1 = html.indexOf("<h1>")
58+
const title = html.slice(
59+
offset1 + "<h1>".length,
60+
html.indexOf("</h1>", offset1)
61+
)
62+
63+
const offset2 = html.indexOf("<blockquote>", offset1)
64+
const desc = html.slice(
65+
offset2 + "<blockquote>".length,
66+
html.indexOf("</blockquote>", offset2)
67+
)
68+
69+
actions.createNode({
70+
id: slug,
71+
slug,
72+
date,
73+
title,
74+
desc,
75+
the_text: html,
76+
internal: {
77+
type: "Texto",
78+
contentDigest: html,
79+
},
80+
parent: node.id, // Required otherwise the node is not cached and a warm build screws up
81+
})
82+
}
83+
}

benchmarks/gabe-fs-text/gen.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
const fs = require("fs")
3+
const path = require("path")
4+
const faker = require(`faker`)
5+
6+
const N = parseInt(process.env.N, 10) || 100
7+
8+
let n = 0
9+
10+
function createArticle(n, sentence, slug) {
11+
const desc = faker.lorem.sentence();
12+
13+
return `
14+
<h1>${sentence.replace(/"/g, '\\"')}</h1>
15+
<blockquote>${desc}</blockquote>
16+
<p>${faker.lorem.paragraphs(1)}</p>
17+
<p>${faker.lorem.paragraphs(1)}</p>
18+
`
19+
}
20+
21+
console.log("Start of gen")
22+
23+
if (fs.existsSync("./generated_articles")) {
24+
TODO // count existing folders. If they are less than given number, just amend to them. Otherwise abort and require a rimraf
25+
} else {
26+
fs.mkdirSync("./generated_articles", { recursive: true })
27+
}
28+
29+
console.log("Now generating " + N + " articles")
30+
for (let i = 0; i < N; ++i) {
31+
const sentence = faker.lorem.sentence()
32+
const slug = faker.helpers.slugify(sentence).toLowerCase()
33+
34+
const date = faker.date.recent(1000).toISOString().slice(0, 10)
35+
36+
fs.writeFileSync(
37+
path.join("./generated_articles", date + '_' + slug + ".txt"),
38+
createArticle(i, sentence, slug)
39+
)
40+
}
41+
console.log("Finished generating " + N + " articles")
42+
console.log("End of gen")

benchmarks/gabe-fs-text/package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "gabe-fs-text",
3+
"private": true,
4+
"description": "Benchmark site for testing baseline plaintext perf with individually generated files",
5+
"author": "Peter van der Zee <pvdz@github>",
6+
"version": "0.1.0",
7+
"license": "MIT",
8+
"scripts": {
9+
"bench": "rm -rf generated_articles; gatsby clean; N=${N:-512} node gen.js; CI=1 node --max_old_space_size=${M:-2}000 node_modules/.bin/gatsby build",
10+
"build": "gatsby build",
11+
"clean": "gatsby clean",
12+
"develop": "gatsby develop",
13+
"format": "prettier --write \"**/*.{js,jsx,json,md}\""
14+
},
15+
"devDependencies": {
16+
"prettier": "2.0.4"
17+
},
18+
"repository": {
19+
"type": "git",
20+
"url": "https://github.com/gatsbyjs/gatsby/tree/master/benchmarks/"
21+
},
22+
"bugs": {
23+
"url": "https://github.com/gatsbyjs/gatsby/issues"
24+
},
25+
"keywords": [
26+
"gatsby",
27+
"benchmark"
28+
],
29+
"dependencies": {
30+
"faker": "^4.1.0",
31+
"gatsby": "^2",
32+
"gatsby-source-filesystem": "^2",
33+
"react": "^16.12.0",
34+
"react-dom": "^16.12.0"
35+
}
36+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Bio component that queries for data
3+
* with Gatsby's useStaticQuery component
4+
*
5+
* See: https://www.gatsbyjs.org/docs/use-static-query/
6+
*/
7+
8+
import React from "react"
9+
10+
const Bio = () => {
11+
return (
12+
<div
13+
style={{
14+
display: `flex`,
15+
marginBottom: '5px',
16+
}}
17+
>
18+
<p>
19+
Written by <strong>Bob</strong> who lives and works in Fan
20+
Srancisco building useful things.
21+
{` `}
22+
<a href={`https://twitter.com/bob`}>
23+
You should follow him on Twitter
24+
</a>
25+
</p>
26+
</div>
27+
)
28+
}
29+
30+
export default Bio

0 commit comments

Comments
 (0)