go 和 python 解析 markdown 速度比较

python 解析 markdown 最快的是misaka

下面是在另外一台电脑上的比较结果:

Parsing the Markdown Syntax document 1000 times...
Mistune: 12.7255s
Mistune (with Cython): 9.74075s
Misaka: 0.550502s
Markdown: 46.4342s
Markdown2: 78.2267s
cMarkdown: 0.664128s

下面是同一台电脑,对python 和 go 解析markdown 速度的比较:

python

misaka 488.649129868 ms
markdown2 68.4613540173 s
markdown 40.3043971062 s

go

knieriem/markdown 35.854568 ms
blackfriday.MarkdownBasic 1.098207145 s
blackfriday.MarkdownCommon 1.607117325 s
opennota/markdown 3.277178642s

go 用的库

python code

# coding: utf-8

import os
import time

NUM = 1000


def benchmark_misaka(text):
    import misaka as m
    # mistune has all these features
    extensions = (
        m.EXT_NO_INTRA_EMPHASIS | m.EXT_FENCED_CODE | m.EXT_AUTOLINK |
        m.EXT_TABLES | m.EXT_STRIKETHROUGH
    )
    md = m.Markdown(m.HtmlRenderer(), extensions=extensions)
    t0 = time.time()
    for i in xrange(NUM):
        md.render(text)
    t1 = time.time()
    print 'misaka', (t1 - t0) * 1000, 'ms'


def benchmark_markdown2(text):
    import markdown2
    extras = ['code-friendly', 'fenced-code-blocks', 'footnotes']
    t0 = time.time()
    for i in xrange(NUM):
        markdown2.markdown(text, extras=extras)
    t1 = time.time()
    print 'markdown2', (t1 - t0), 's'


def benchmark_markdown(text):
    import markdown
    t0 = time.time()
    for i in xrange(NUM):
        markdown.markdown(text, ['extra'])
    t1 = time.time()
    print 'markdown', (t1 - t0), 's'


if __name__ == '__main__':
    root = os.path.dirname(__file__)
    filepath = os.path.join(
        root, 'markdown_documentation_syntax.text'
    )
    with open(filepath, 'r') as f:
        text = f.read()

    benchmark_misaka(text)
    benchmark_markdown2(text)
    benchmark_markdown(text)

go code

package main

import (
	//"bufio"
	"bytes"
	"fmt"
	"github.com/knieriem/markdown"
	"github.com/russross/blackfriday"
	//"os"
	"io/ioutil"
	"strings"
	"time"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func main() {
	//p := NewParser(nil)
	p := markdown.NewParser(&markdown.Extensions{Smart: true})

	dat, err := ioutil.ReadFile("markdown_documentation_syntax.text")
	check(err)
	//fmt.Println(dat)
	//fmt.Println(string(dat))

	var buf bytes.Buffer

	r2 := strings.NewReader(string(dat))
	fhtml := markdown.ToHTML(&buf)
	t1 := time.Now()
	for j := 0; j < 1000; j++ {
		p.Markdown(r2, fhtml)
	}
	t2 := time.Now()
	fmt.Println("knieriem/markdown", t2.Sub(t1))

	//output := blackfriday.MarkdownBasic(dat)
	//fmt.Println(output)
	//fmt.Println(string(output))

	t1 = time.Now()
	for j := 0; j < 1000; j++ {
		blackfriday.MarkdownBasic(dat)
	}
	t2 = time.Now()
	fmt.Println("blackfriday.MarkdownBasic", t2.Sub(t1))

	t1 = time.Now()
	for j := 0; j < 1000; j++ {
		blackfriday.MarkdownCommon(dat)
	}
	t2 = time.Now()
	fmt.Println("blackfriday.MarkdownCommon", t2.Sub(t1))

	fmt.Println("done")
}

github.com/opennota/markdown sample

package main

import (
	//"bufio"
	//"bytes"
	"fmt"
	"github.com/opennota/markdown"
	//"os"
	"io/ioutil"
	//"strings"
	"time"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func main() {

	dat, err := ioutil.ReadFile("markdown_documentation_syntax.text")
	check(err)

	md := markdown.New(markdown.XHTMLOutput(true), markdown.Nofollow(true))

	t1 := time.Now()
	for j := 0; j < 1000; j++ {
		//fmt.Println(md.RenderToString(dat))
		md.RenderToString(dat)
	}
	t2 := time.Now()
	fmt.Println("opennota/mdtool", t2.Sub(t1))

	fmt.Println("done")
}

Relative Articles