Faster parseBoard (v3)

Revision 3 of this benchmark created on


Setup

function error(e) {
	throw new Error(e)
}

function createBoard() {
  return positions.reduce((acc, p) => {
    acc[p] = null
    return acc
  }, {})
}

const positions = [
  'f11',
  'e10',
  'f10',
  'g10',
  'd9',
  'e9',
  'f9',
  'g9',
  'h9',
  'c8',
  'd8',
  'e8',
  'f8',
  'g8',
  'h8',
  'i8',
  'b7',
  'c7',
  'd7',
  'e7',
  'f7',
  'g7',
  'h7',
  'i7',
  'k7',
  'a6',
  'b6',
  'c6',
  'd6',
  'e6',
  'f6',
  'g6',
  'h6',
  'i6',
  'k6',
  'l6',
  'a5',
  'b5',
  'c5',
  'd5',
  'e5',
  'f5',
  'g5',
  'h5',
  'i5',
  'k5',
  'l5',
  'a4',
  'b4',
  'c4',
  'd4',
  'e4',
  'f4',
  'g4',
  'h4',
  'i4',
  'k4',
  'l4',
  'a3',
  'b3',
  'c3',
  'd3',
  'e3',
  'f3',
  'g3',
  'h3',
  'i3',
  'k3',
  'l3',
  'a2',
  'b2',
  'c2',
  'd2',
  'e2',
  'f2',
  'g2',
  'h2',
  'i2',
  'k2',
  'l2',
  'a1',
  'b1',
  'c1',
  'd1',
  'e1',
  'f1',
  'g1',
  'h1',
  'i1',
  'k1',
  'l1',
]

const initialPosition = 'b/qbk/n1b1n/r5r/ppppppppp/11/5P5/4P1P4/3P1B1P3/2P2B2P2/1PRNQBKNRP1'

Test runner

Ready to run.

Testing in
TestOps/sec
0.7.1
function parseBoard(source) {
  const board = createBoard()

  let normalized = ''

  for (let i = 0; i < source.length; i++) {
    const current = source[i]

    if (current === '1') {
      const next = source[i + 1]

      if (next === '0') {
        i++
        normalized += '__________'
      } else if (next === '1') {
        i++
        normalized += '___________'
      } else {
        normalized += '_'
      }
    } else if (current === '2') {
      normalized += '__'
    } else if (current === '3') {
      normalized += '___'
    } else if (current === '4') {
      normalized += '____'
    } else if (current === '5') {
      normalized += '_____'
    } else if (current === '6') {
      normalized += '______'
    } else if (current === '7') {
      normalized += '_______'
    } else if (current === '8') {
      normalized += '________'
    } else if (current === '9') {
      normalized += '_________'
    } else if (current !== '/') {
      normalized += source[i]
    }
  }

  if (normalized.length !== positions.length) {
    error('parse failed: invalid length')
  }

  let black = false
  let white = false

  for (let i = 0; i < positions.length; i++) {
    const piece = normalized[i]
    const position = positions[i]

    if (piece === 'k') {
      if (black) {
        error('parse failed: multiple black kings')
      }

      black = true
      board[position] = 'k'
    } else if (piece === 'K') {
      if (white) {
        error('parse failed: multiple white kings')
      }

      white = true
      board[position] = 'K'
    } else if (
      piece === 'p' ||
      piece === 'r' ||
      piece === 'n' ||
      piece === 'b' ||
      piece === 'q' ||
      piece === 'P' ||
      piece === 'R' ||
      piece === 'N' ||
      piece === 'B' ||
      piece === 'Q'
    ) {
      board[position] = piece
    } else if (piece !== '_') {
      error('parse failed: invalid piece')
    }
  }

  return board
}

parseBoard(initialPosition)
ready
Single loop
function parseBoard(source) {
  const board = createBoard()

  let black = false
  let white = false
  let j = 0

  for (let i = 0; i < source.length; i++) {
    const current = source[i]
    const position = positions[j]

    if (current === '1') {
      const next = source[i + 1]

      if (next === '0') {
        j += 10
        i++
      } else if (next === '1') {
        j += 11
        i++
      } else {
        j++
      }
    } else if (current === '2') {
      j += 2
    } else if (current === '3') {
      j += 3
    } else if (current === '4') {
      j += 4
    } else if (current === '5') {
      j += 5
    } else if (current === '6') {
      j += 6
    } else if (current === '7') {
      j += 7
    } else if (current === '8') {
      j += 8
    } else if (current === '9') {
      j += 9
    } else if (current === 'k') {
      if (black) {
        error('parse failed: multiple black kings')
      }

      black = true
      board[position] = 'k'
      j++
    } else if (current === 'K') {
      if (white) {
        error('parse failed: multiple white kings')
      }

      white = true
      board[position] = 'K'
      j++
    } else if (
      current === 'b' ||
      current === 'B' ||
      current === 'n' ||
      current === 'N' ||
      current === 'p' ||
      current === 'P' ||
      current === 'Q' ||
      current === 'q' ||
      current === 'r' ||
      current === 'R'
    ) {
      board[position] = current
      j++
    } else if (current !== '/') {
      error(`parse failed: invalid piece ${current}`)
    }
  }

  if (j !== 91) {
    error(`parse failed: invalid length ${j}`)
  }

  return board
}

parseBoard(initialPosition)
ready
Single loop (switch)
function parseBoard(source) {
  const board = createBoard()

  let black = false
  let white = false
  let j = 0

  for (let i = 0; i < source.length; i++) {
    const current = source[i]
    const position = positions[j]

    switch (current) {
      case '1':
        switch (source[i + 1]) {
          case '0':
            j += 10
            i++
            continue
          case '1':
            j += 11
            i++
            continue
          default:
            j++
            continue
        }
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        j += parseInt(current)
        continue
      case 'K':
        if (white) {
          error('parse failed: multiple white kings')
        }

        white = true
        board[position] = 'K'
        j++
        continue
      case 'k':
        if (black) {
          error('parse failed: multiple black kings')
        }

        black = true
        board[position] = 'k'
        j++
        continue
      case 'b':
      case 'B':
      case 'n':
      case 'N':
      case 'p':
      case 'P':
      case 'Q':
      case 'q':
      case 'r':
      case 'R':
        board[position] = current
        j++
        continue
      case '/':
        continue
    }

    error(`parse failed: invalid piece ${current}`)
  }

  if (j !== 91) {
    error(`parse failed: invalid length ${j}`)
  }

  return board
}

parseBoard(initialPosition)
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.