go語言提取注釋 GO注釋分析

php和go語言哪個好

前言

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、葉集網(wǎng)絡(luò)推廣、微信小程序、葉集網(wǎng)絡(luò)營銷、葉集企業(yè)策劃、葉集品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供葉集建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.muchs.cn

最近工作中遇到的一個場景,php項(xiàng)目中需要使用一個第三方的功能,而恰好有一個用Golang寫好的類庫。那么問題就來了,要如何實(shí)現(xiàn)不同語言之間的通信呢?下面就來一起看看吧。

常規(guī)的方案

1、 用Golang寫一個http/TCP服務(wù),php通過http/TCP與Golang通信

2、將Golang經(jīng)過較多封裝,做為php擴(kuò)展。

3、PHP通過系統(tǒng)命令,調(diào)取Golang的可執(zhí)行文件

存在的問題

1、http請求,網(wǎng)絡(luò)I/O將會消耗大量時(shí)間

2、需要封裝大量代碼

3、PHP每調(diào)取一次Golang程序,就需要一次初始化,時(shí)間消耗很多

優(yōu)化目標(biāo)

1、Golang程序只初始化一次(因?yàn)槌跏蓟芎臅r(shí))

2、所有請求不需要走網(wǎng)絡(luò)

3、盡量不大量修改代碼

解決方案

1、簡單的Golang封裝,將第三方類庫編譯生成為一個可執(zhí)行文件

2、PHP與Golang通過雙向管道通信

使用雙向管道通信優(yōu)勢

1:只需要對原有Golang類庫進(jìn)行很少的封裝

2:性能最佳 (IPC通信是進(jìn)程間通信的最佳途徑)

3:不需要走網(wǎng)絡(luò)請求,節(jié)約大量時(shí)間

4:程序只需初始化一次,并一直保持在內(nèi)存中

具體實(shí)現(xiàn)步驟

1:類庫中的原始調(diào)取demo

package main

import (

"fmt"

"github.com/yanyiwu/gojieba"

"strings"

)

func main() {

x := gojieba.NewJieba()

defer x.Free()

s := "小明碩士畢業(yè)于中國科學(xué)院計(jì)算所,后在日本京都大學(xué)深造"

words := x.CutForSearch(s, true)

fmt.Println(strings.Join(words, "/"))

}

保存文件為main.go,就可以運(yùn)行

2:調(diào)整后代碼為:

package main

import (

"bufio"

"fmt"

"github.com/yanyiwu/gojieba"

"io"

"os"

"strings"

)

func main() {

x := gojieba.NewJieba(

"/data/tmp/jiebaDict/jieba.dict.utf8",

"/data/tmp/jiebaDict/hmm_model.utf8",

"/data/tmp/jiebaDict/user.dict.utf8"

)

defer x.Free()

inputReader := bufio.NewReader(os.Stdin)

for {

s, err := inputReader.ReadString('\n')

if err != nil err == io.EOF {

break

}

s = strings.TrimSpace(s)

if s != "" {

words := x.CutForSearch(s, true)

fmt.Println(strings.Join(words, " "))

} else {

fmt.Println("get empty \n")

}

}

}

只需要簡單的幾行調(diào)整,即可實(shí)現(xiàn):從標(biāo)準(zhǔn)輸入接收字符串,經(jīng)過分詞再輸出

測試:

# go build test

# ./test

# //等待用戶輸入,輸入”這是一個測試“

# 這是 一個 測試 //程序

3:使用cat與Golang通信做簡單測試

//準(zhǔn)備一個title.txt,每行是一句文本

# cat title.txt | ./test

正常輸出,表示cat已經(jīng)可以和Golang正常交互了

4:PHP與Golang通信

以上所示的cat與Golang通信,使用的是單向管道。即:只能從cat向Golang傳入數(shù)據(jù),Golang輸出的數(shù)據(jù)并沒有傳回給cat,而是直接輸出到屏幕。但文中的需求是:php與Golang通信。即php要傳數(shù)據(jù)給Golang,同時(shí)Golang也必須把執(zhí)行結(jié)果返回給php。因此,需要引入雙向管道。

在PHP中管道的使用:popen("/path/test") ,具體就不展開說了,因?yàn)榇朔椒ń鉀Q不了文中的問題。

雙向管道:

$descriptorspec = array(

0 = array("pipe", "r"),

1 = array("pipe", "w")

);

$handle = proc_open(

'/webroot/go/src/test/test',

$descriptorspec,

$pipes

);

fwrite($pipes['0'], "這是一個測試文本\n");

echo fgets($pipes[1]);

解釋:使用proc_open打開一個進(jìn)程,調(diào)用Golang程序。同時(shí)返回一個雙向管道pipes數(shù)組,php向$pipe['0']中寫數(shù)據(jù),從$pipe['1']中讀數(shù)據(jù)。

好吧,也許你已經(jīng)發(fā)現(xiàn),我是標(biāo)題檔,這里重點(diǎn)要講的并不只是PHP與Golang如何通信。而是在介紹一種方法: 通過雙向管道讓任意語言通信。(所有語言都會實(shí)現(xiàn)管道相關(guān)內(nèi)容)

測試:

通過對比測試,計(jì)算出各個流程占用的時(shí)間。下面提到的title.txt文件,包含100萬行文本,每行文本是從b2b平臺取的商品標(biāo)題

1: 整體流程耗時(shí)

time cat title.txt | ./test /dev/null

耗時(shí):14.819秒,消耗時(shí)間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù),將結(jié)果返回到屏幕

2:計(jì)算分詞函數(shù)耗時(shí)。方案:去除分詞函數(shù)的調(diào)取,即:注釋掉Golang源代碼中的調(diào)取分詞那行的代碼

time cat title.txt | ./test /dev/null

耗時(shí):1.817秒時(shí)間,消耗時(shí)間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù),將結(jié)果返回到屏幕

分詞耗時(shí) = (第一步耗時(shí)) - (以上命令所耗時(shí))

分詞耗時(shí) : 14.819 - 1.817 = 13.002秒

3:測試cat進(jìn)程與Golang進(jìn)程之間通信所占時(shí)間

time cat title.txt /dev/null

耗時(shí):0.015秒,消耗時(shí)間包含:

進(jìn)程cat讀出文本

通過管道將數(shù)據(jù)傳入Golang

go處理數(shù)據(jù),將結(jié)果返回到屏幕

管道通信耗時(shí):(第二步耗時(shí)) - (第三步耗時(shí))

管道通信耗時(shí): 1.817 - 0.015 = 1.802秒

4:PHP與Golang通信的時(shí)間消耗

編寫簡單的php文件:

?php

$descriptorspec = array(

0 = array("pipe", "r"),

1 = array("pipe", "w")

);

$handle = proc_open(

'/webroot/go/src/test/test',

$descriptorspec,

$pipes

);

$fp = fopen("title.txt", "rb");

while (!feof($fp)) {

fwrite($pipes['0'], trim(fgets($fp))."\n");

echo fgets($pipes[1]);

}

fclose($pipes['0']);

fclose($pipes['1']);

proc_close($handle);

流程與上面基本一致,讀出title.txt內(nèi)容,通過雙向管道傳入Golang進(jìn)程分詞后,再返回給php (比上面的測試多一步:數(shù)據(jù)再通過管道返回)

time php popen.php /dev/null

耗時(shí):24.037秒,消耗時(shí)間包含:

進(jìn)程PHP讀出文本

通過管道將數(shù)據(jù)傳入Golang

Golang處理數(shù)據(jù)

Golang將返回結(jié)果再寫入管道,PHP通過管道接收數(shù)據(jù)

將結(jié)果返回到屏幕

結(jié)論:

1 :整個分詞過程中的耗時(shí)分布

使用cat控制邏輯耗時(shí): 14.819 秒

使用PHP控制邏輯耗時(shí): 24.037 秒(比cat多一次管道通信)

單向管道通信耗時(shí): 1.8 秒

Golang中的分詞函數(shù)耗時(shí): 13.002 秒

2:分詞函數(shù)的性能: 單進(jìn)程,100萬商品標(biāo)題分詞,耗時(shí)13秒

以上時(shí)間只包括分詞時(shí)間,不包括詞典載入時(shí)間。但在本方案中,詞典只載入一次,所以載入詞典時(shí)間可以忽略(1秒左右)

3:PHP比cat慢 (這結(jié)論有點(diǎn)多余了,呵呵)

語言層面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%

單進(jìn)程對比測試的話,應(yīng)該不會有哪個語言比cat更快。

相關(guān)問題:

1:以上Golang源碼中寫的是一個循環(huán),也就是會一直從管道中讀數(shù)據(jù)。那么存在一個問題:是不是php進(jìn)程結(jié)束后,Golang的進(jìn)程還會一直存在?

管道機(jī)制自身可解決此問題。管道提供兩個接口:讀、寫。當(dāng)寫進(jìn)程結(jié)束或者意外掛掉時(shí),讀進(jìn)程也會報(bào)錯,以上Golang源代碼中的err邏輯就會執(zhí)行,Golang進(jìn)程結(jié)束。

但如果PHP進(jìn)程沒有結(jié)束,只是暫時(shí)沒有數(shù)據(jù)傳入,此時(shí)Golang進(jìn)程會一直等待。直到php結(jié)束后,Golang進(jìn)程才會自動結(jié)束。

2:能否多個php進(jìn)程并行讀寫同一個管道,Golang進(jìn)程同時(shí)為其服務(wù)?

不可以。管道是單向的,如果多個進(jìn)程同時(shí)向管道中寫,那Golang的返回值就會錯亂。

可以多開幾個Golang進(jìn)程實(shí)現(xiàn),每個php進(jìn)程對應(yīng)一個Golang進(jìn)程。

最后,上面都是瞎扯的。如果你了解管道、雙向管道,上面的解釋對你基本沒啥用。但如果你不了解管道,調(diào)試上面的代碼沒問題,但稍有修改就有可能掉坑里。

Go語言編程入門時(shí)需要注意什么

剛?cè)腴TGo語言小白需要注意以下五點(diǎn):

1、注意書寫代碼的一些規(guī)范吧,特別是注意大小寫、英文標(biāo)點(diǎn)符號區(qū)別等,在特別的位置寫上注釋。

2、主要是理解偽代碼所描述的算法,偽代碼要注意是不能直接運(yùn)行的。

3、注意編譯器版本與書籍上所介紹版本是否一致,也注意特殊符號,印刷版本可能與實(shí)際不一致。

4、書上的版本和當(dāng)前所用的版本是否一致,有些情況下書上版本在現(xiàn)在來用已經(jīng)過時(shí)了。

5、邏輯走通;給自己信心,其實(shí)起步階段不難的。

Go語言基礎(chǔ)語法(一)

本文介紹一些Go語言的基礎(chǔ)語法。

先來看一個簡單的go語言代碼:

go語言的注釋方法:

代碼執(zhí)行結(jié)果:

下面來進(jìn)一步介紹go的基礎(chǔ)語法。

go語言中格式化輸出可以使用 fmt 和 log 這兩個標(biāo)準(zhǔn)庫,

常用方法:

示例代碼:

執(zhí)行結(jié)果:

更多格式化方法可以訪問中的fmt包。

log包實(shí)現(xiàn)了簡單的日志服務(wù),也提供了一些格式化輸出的方法。

執(zhí)行結(jié)果:

下面來介紹一下go的數(shù)據(jù)類型

下表列出了go語言的數(shù)據(jù)類型:

int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲的是一個地址,這個地址存儲最終的值。

常量是在程序編譯時(shí)就確定下來的值,程序運(yùn)行時(shí)無法改變。

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

Go 語言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。

算術(shù)運(yùn)算符:

關(guān)系運(yùn)算符:

邏輯運(yùn)算符:

位運(yùn)算符:

賦值運(yùn)算符:

指針相關(guān)運(yùn)算符:

下面介紹一下go語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯(lián)用,這里不做介紹。

if語法格式如下:

if ... else :

else if:

示例代碼:

語法格式:

另外,添加 fallthrough 會強(qiáng)制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。

示例代碼:

執(zhí)行結(jié)果:

下面介紹幾種循環(huán)語句:

執(zhí)行結(jié)果:

執(zhí)行結(jié)果:

也可以通過標(biāo)記退出循環(huán):

--THE END--

求GO語言大能解答,go 1.1的http.Client.Do方法是不是有問題

看一下基本說明。

使用wego的前提是你已經(jīng)對基因或元件做了GO的注釋,也就是說,你已經(jīng)有了每個gene的GO號,然后才是用wego去做分類圖,或差異分布圖。

blast2go則是用來做GO注釋的,也就是說,你還不知道基因與GO之間的關(guān)系,這時(shí)可以用blast2go建立這樣一個關(guān)系(注釋)。

所以,你可以先用blast2go來注釋,再用wego來分析。

新聞名稱:go語言提取注釋 GO注釋分析
地址分享:http://www.muchs.cn/article12/hhicdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航品牌網(wǎng)站設(shè)計(jì)網(wǎng)站收錄、建站公司、軟件開發(fā)網(wǎng)頁設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化