Permalink
Browse files

Precompile langlist [performance]

About 25% of the Intuition start-up time is spent generating the language list
from scanning languages/**/*.json and Names.php.

Optimise that by precompiling it with a script.
  • Loading branch information...
Krinkle committed Mar 15, 2016
1 parent c0ba6d7 commit 9daa30e6cdaa88999a39418ca115c07ceff36956
Showing with 250 additions and 22 deletions.
  1. +1 −3 composer.json
  2. +26 −19 includes/Intuition.php
  3. +176 −0 language/langlist.php
  4. +28 −0 scripts/compileLanglist.php
  5. +19 −0 tests/phpunit/IntuitionTest.php
@@ -2,15 +2,13 @@
"name": "krinkle/intuition",
"description": "Framework for localisation in PHP.",
"license": "CC-BY-3.0",
"require": {
"php": ">=5.5"
},
"autoload": {
"files": [
"ToolStart.php"
]
},
"require": {
"php": ">=5.5",
"krinkle/toollabs-base": "~0.7.0"
},
"require-dev": {
@@ -656,7 +656,7 @@ public function getLangName( $lang = false ) {
* Return all known languages.
* @return array
*/
public function getLangNames() {
protected function getLangNames() {
// Lazy-load and cache
if ( $this->langNames === null ) {
$path = $this->localBaseDir . '/language/mw-classes/Names.php';
@@ -680,27 +680,34 @@ public function getLangNames() {
* @return array Language names keyed by language code
*/
public function getAvailableLangs() {
// Lazy-load and cache
if ( $this->availableLanguages === null ) {
$messageFiles = glob( $this->localBaseDir . '/language/messages/*/*.json' );
$languages = array_values( array_unique( array_map(
function ( $filename ) {
return basename( $filename, '.json' );
},
$messageFiles
) ) );
$availableLanguages = array();
foreach ( $languages as $lang ) {
$availableLanguages[$lang] = $this->getLangName( $lang );
}
ksort( $availableLanguages );
if ( !$this->availableLanguages ) {
$this->availableLanguages = require $this->localBaseDir . '/language/langlist.php';
}
return $this->availableLanguages;
}
$this->availableLanguages = $availableLanguages;
/**
* Generate a list of all languages available in at least one domain.
* @return array Language names keyed by language code
*/
public function generateLanguageList() {
$messageFiles = glob( $this->localBaseDir . '/language/messages/*/*.json' );
$languages = array_map(
function ( $filename ) {
return basename( $filename, '.json' );
},
$messageFiles
);
$languages = array_values( array_unique( $languages ) );
$availableLanguages = array();
foreach ( $languages as $lang ) {
$availableLanguages[$lang] = $this->getLangName( $lang );
}
ksort( $availableLanguages );
return $this->availableLanguages;
return $availableLanguages;
}
/* Domain functions
@@ -0,0 +1,176 @@
<?php return array (
'aeb-latn' => 'Tûnsî',
'af' => 'Afrikaans',
'ak' => 'Akan',
'am' => 'አማርኛ',
'ar' => 'العربية',
'arc' => 'ܐܪܡܝܐ',
'arq' => 'جازايرية',
'as' => 'অসমীয়া',
'ast' => 'asturianu',
'az' => 'azərbaycanca',
'azb' => 'تۆرکجه',
'ba' => 'башҡортса',
'bbc-latn' => 'Batak Toba',
'be' => 'беларуская',
'be-tarask' => 'беларуская (тарашкевіца)‎',
'bg' => 'български',
'bgn' => 'بلوچی رخشانی',
'bho' => 'भोजपुरी',
'bjn' => 'Bahasa Banjar',
'bn' => 'বাংলা',
'br' => 'brezhoneg',
'bs' => 'bosanski',
'bxr' => 'буряад',
'ca' => 'català',
'ce' => 'нохчийн',
'ckb' => 'کوردیی ناوەندی',
'cs' => 'čeština',
'cv' => 'Чӑвашла',
'cy' => 'Cymraeg',
'da' => 'dansk',
'de' => 'Deutsch',
'de-formal' => 'Deutsch (Sie-Form)‎',
'diq' => 'Zazaki',
'dsb' => 'dolnoserbski',
'egl' => 'Emiliàn',
'el' => 'Ελληνικά',
'eml' => 'emiliàn e rumagnòl',
'en' => 'English',
'en-ca' => 'Canadian English',
'en-gb' => 'British English',
'eo' => 'Esperanto',
'es' => 'español',
'et' => 'eesti',
'eu' => 'euskara',
'fa' => 'فارسی',
'fi' => 'suomi',
'fo' => 'føroyskt',
'fr' => 'français',
'frp' => 'arpetan',
'frr' => 'Nordfriisk',
'fy' => 'Frysk',
'ga' => 'Gaeilge',
'gl' => 'galego',
'gor' => '',
'grc' => 'Ἀρχαία ἑλληνικὴ',
'gu' => 'ગુજરાતી',
'he' => 'עברית',
'hi' => 'हिन्दी',
'hr' => 'hrvatski',
'hsb' => 'hornjoserbsce',
'ht' => 'Kreyòl ayisyen',
'hu' => 'magyar',
'hy' => 'Հայերեն',
'ia' => 'interlingua',
'id' => 'Bahasa Indonesia',
'ig' => 'Igbo',
'ilo' => 'Ilokano',
'inh' => 'ГӀалгӀай',
'is' => 'íslenska',
'it' => 'italiano',
'ja' => '日本語',
'jv' => 'Basa Jawa',
'ka' => 'ქართული',
'kk-cyrl' => 'қазақша (кирил)‎',
'km' => 'ភាសាខ្មែរ',
'kn' => 'ಕನ್ನಡ',
'ko' => '한국어',
'krl' => '',
'ksh' => 'Ripoarisch',
'ku-latn' => 'Kurdî (latînî)‎',
'ky' => 'Кыргызча',
'la' => 'Latina',
'lb' => 'Lëtzebuergesch',
'lez' => 'лезги',
'lki' => '',
'lrc' => 'لوری مینجایی',
'lt' => 'lietuvių',
'lv' => 'latviešu',
'lzh' => '文言',
'lzz' => 'Lazuri',
'map-bms' => 'Basa Banyumasan',
'mg' => 'Malagasy',
'min' => 'Baso Minangkabau',
'mk' => 'македонски',
'ml' => 'മലയാളം',
'mn' => 'монгол',
'mr' => 'मराठी',
'ms' => 'Bahasa Melayu',
'mt' => 'Malti',
'my' => 'မြန်မာဘာသာ',
'mzn' => 'مازِرونی',
'nah' => 'Nāhuatl',
'nap' => 'Napulitano',
'nb' => 'norsk bokmål',
'nds' => 'Plattdüütsch',
'nds-nl' => 'Nedersaksies',
'ne' => 'नेपाली',
'new' => 'नेपाल भाषा',
'nl' => 'Nederlands',
'nl-informal' => 'Nederlands (informeel)‎',
'nn' => 'norsk nynorsk',
'no' => 'norsk bokmål',
'oc' => 'occitan',
'olo' => '',
'or' => 'ଓଡ଼ିଆ',
'os' => 'Ирон',
'pa' => 'ਪੰਜਾਬੀ',
'pdc' => 'Deitsch',
'pfl' => 'Pälzisch',
'pi' => 'पालि',
'pl' => 'polski',
'pms' => 'Piemontèis',
'ps' => 'پښتو',
'pt' => 'português',
'pt-br' => 'português do Brasil',
'qqq' => 'English',
'qu' => 'Runa Simi',
'ro' => 'română',
'roa-tara' => 'tarandíne',
'ru' => 'русский',
'rue' => 'русиньскый',
'sa' => 'संस्कृतम्',
'sah' => 'саха тыла',
'scn' => 'sicilianu',
'sco' => 'Scots',
'sd' => 'سنڌي',
'sh' => 'srpskohrvatski / српскохрватски',
'shy-latn' => '',
'si' => 'සිංහල',
'sk' => 'slovenčina',
'sl' => 'slovenščina',
'so' => 'Soomaaliga',
'sq' => 'shqip',
'sr-ec' => 'српски (ћирилица)‎',
'sr-el' => 'srpski (latinica)‎',
'sv' => 'svenska',
'sw' => 'Kiswahili',
'ta' => 'தமிழ்',
'te' => 'తెలుగు',
'tet' => 'tetun',
'th' => 'ไทย',
'ti' => 'ትግርኛ',
'tl' => 'Tagalog',
'tly' => 'толышә зывон',
'tr' => 'Türkçe',
'tt' => 'татарча/tatarça',
'tt-cyrl' => 'татарча',
'ttt' => '',
'tyv' => 'тыва дыл',
'tzm' => 'ⵜⴰⵎⴰⵣⵉⵖⵜ',
'udm' => 'удмурт',
'ug-arab' => 'ئۇيغۇرچە',
'uk' => 'українська',
'ur' => 'اردو',
'uz' => 'oʻzbekcha/ўзбекча',
'vep' => 'vepsän kel’',
'vi' => 'Tiếng Việt',
'wuu' => '吴语',
'yi' => 'ייִדיש',
'zea' => 'Zeêuws',
'zh-hans' => '中文(简体)‎',
'zh-hant' => '中文(繁體)‎',
'zh-hk' => '中文(香港)‎',
'zh-tw' => '中文(台灣)‎',
);
@@ -0,0 +1,28 @@
<?php
/**
* Extract language data from MediaWiki core.
*
* @copyright 2011-2015 See AUTHORS.txt
* @license CC-BY 3.0 <https://creativecommons.org/licenses/by/3.0/>
* @package intuition
*/
$dest = dirname( __DIR__ ) . '/language';
if ( !is_writable( $dest ) ) {
echo "error: Unable to write to $dest\n";
exit(1);
}
require_once __DIR__ . '/../vendor/autoload.php';
$intuition = new Intuition( 'general' );
$data = $intuition->generateLanguageList();
$code = '<?php return ' . var_export( $data, true ) . ';';
$destFile = "$dest/langlist.php";
$written = file_put_contents( $destFile, $code );
if ( !$written ) {
echo "error: Failed to write $destFile\n";
exit(1);
}
@@ -419,4 +419,23 @@ public function testGetDomainInfo() {
$this->i18n->getDomainInfo( '-x-unknown' )
);
}
/**
* @covers Intuition::getAvailableLangs
*/
public function testGetAvailableLangs() {
$langs = $this->i18n->getAvailableLangs();
$this->assertEquals( 'array', gettype( $langs ) );
$this->assertTrue( count( $langs ) > 3 );
$this->assertEquals( 'English', $langs['en'] );
}
/**
* @covers Intuition::generateLanguageList
*/
public function testAvailableLangs() {
$precompiled = $this->i18n->getAvailableLangs();
$langlist = $this->i18n->generateLanguageList();
$this->assertEquals( $langlist, $precompiled, 'Precompiled language list is up-to-date' );
}
}

0 comments on commit 9daa30e

Please sign in to comment.