400 тысяч GitHub-репозиториев, 1 миллиард файлов, 14 ТБ кода: пробелы или табуляция?

Разработчик из Google Фелипе Хоффа решил получить ответ на один из самых популярных вопросов среди программистов: что же лучше, пробелы или табуляция? И получил, проанализировав 400 тысяч репозиториев на GitHub. 

1-JK_4wcGgD3OTUq0weuIXfw

Правила:

  • Источник данных: GitHub-файлы, хранящиеся в BigQuery.
  • Рейтинг имеет значение: были отобраны только 400 тысяч репозиториев с наибольшим количеством звёзд, полученных с января по май 2016 года.
  • Никаких маленьких файлов: в каждом файле должно быть не менее 10 строк, начинающихся с пробела или символа табуляции.
  • Никаких дубликатов: дублирующиеся файлы участвуют лишь один раз, вне зависимости от того, в скольких репозиториях они находятся.
  • Один голос на файл: в некоторых файлах используются и пробелы, и табуляция — в таком случае выбирается более часто используемый метод.
  • Языки: рассматриваются файлы с расширениями: .java, .h, .js, .c, .php, .html, .cs, .json, .py, .cpp, .xml, .rb, .cc, .go.

Числа

1-DlSsNSGduZWkLBFFq8Y3zQ

Принцип работы

Использовалась уже существующая таблица [bigquery-public-data:github_repos.sample_files], в которой указаны файлы из 400 000 топовых репозиториев. Из неё было извлечено содержимое файлов с вышеупомянутыми расширениями:

SELECT a.id id, size, content, binary, copies, sample_repo_name , sample_path
FROM (
SELECT id, FIRST(path) sample_path, FIRST(repo_name) sample_repo_name
FROM [bigquery-public-data:github_repos.sample_files]
WHERE REGEXP_EXTRACT(path, r'\.([^\.]*)$') IN ('java','h','js','c','php','html','cs','json','py','cpp','xml','rb','cc','go')
GROUP BY id
) a
JOIN [bigquery-public-data:github_repos.contents] b
ON a.id=b.id

864.6s elapsed, 1.60 TB processed

Этот запрос занял прилично времени, так как происходило объединение таблицы в 190 миллионов строк с таблицей в 70 миллионов строк. Но вы можете не беспокоиться насчёт его запуска, поскольку автор выложил результат в [fh-bigquery:github_extracts.contents_top_repos_top_langs].

В таблице [contents] каждый уникальный файл отображается один раз. Чтобы увидеть общее число файлов и их размер, используйте:

SELECT SUM(copies) total_files, SUM(copies*size) total_size
FROM [fh-bigquery:github_extracts.contents_top_repos_top_langs]

1 billion files, 14 terabytes of code

1-LynX1o8a9gPTJ1oWCAj0Aw

Для получения рейтинга по вышеобозначенным правилам введите:

SELECT ext, tabs, spaces, countext, LOG((spaces+1)/(tabs+1)) lratio
FROM (
SELECT REGEXP_EXTRACT(sample_path, r'\.([^\.]*)$') ext,
SUM(best='tab') tabs, SUM(best='space') spaces,
COUNT(*) countext
FROM (
SELECT sample_path, sample_repo_name, IF(SUM(line=' ')>SUM(line='\t'), 'space', 'tab') WITHIN RECORD best,
COUNT(line) WITHIN RECORD c
FROM (
SELECT LEFT(SPLIT(content, '\n'), 1) line, sample_path, sample_repo_name
FROM [fh-bigquery:github_extracts.contents_top_repos_top_langs]
HAVING REGEXP_MATCH(line, r'[ \t]')
)
HAVING c>10 # at least 10 lines that start with space or tab
)
GROUP BY ext
)
ORDER BY countext DESC
LIMIT 100

16.0s elapsed, 133 GB processed

Проанализировать 133 гигабайта кода за 16 секунд? Да, BigQuery это может 🙂

А какой способ создания отступов предпочитаете вы?

или посмотреть результаты

Загрузка ... Загрузка ...

Источник: medium.com