Heim >Backend-Entwicklung >PHP-Tutorial >Rufen Sie cjieba mit PHPs FFI auf

Rufen Sie cjieba mit PHPs FFI auf

藏色散人
藏色散人nach vorne
2020-11-19 15:21:404187Durchsuche

Empfohlen: „PHP-Video-Tutorial

phpjieba_ffi

Verwenden Sie FFI von PHP 7.4, um die dynamische Bibliothek zu testen, die die Cjieba-Wortsegmentierung direkt aufruft.

Der Grund für die Wahl von CJieba ist, dass FFI den C-Aufruf verwendet Wenn Sie Cpp verwenden, müssen Sie es selbst packen und dann externes C verwenden, damit der Compiler eine standardmäßige dynamische C-Bibliothek generieren kann. Aufgetretene Probleme ::isNull ($x)

Arrays in Zeigerform können nicht mit foreach verwendet werden

Schleifen auf Zeigerform-Arrays

Bei Betrachtung des C-Codes haben wir festgestellt, dass der Cut-Teil wie folgt lautet:

CJiebaWord* Cut(Jieba handle, const char* sentence, size_t len) {
  cppjieba::Jieba* x = (cppjieba::Jieba*)handle;
  vector<string> words;
  string s(sentence, len);
  x->Cut(s, words);
  
  CJiebaWord* res = (CJiebaWord*)malloc(sizeof(CJiebaWord) * (words.size() + 1));
  size_t offset = 0;
  for (size_t i = 0; i < words.size(); i++) {
    res[i].word = sentence + offset;
    res[i].len = words[i].size();
    offset += res[i].len;
  }
  if (offset != len) {
    free(res);
    return NULL;
  }
  res[words.size()].word = NULL;
  res[words.size()].len = 0;
  return res;
}

gibt a zurück Strukturzeiger. In der C-Sprache ist der Array-Name tatsächlich die Zeigeradresse der ersten Variablen im Array, sodass sie durch die Operation der Zeigeradresse ++ durchlaufen werden kann.

Für dieses Array habe ich zunächst eine foreach-Schleife verwendet und später wie bei C direkt den Zeiger++ verwendet und festgestellt, dass dies machbar ist, da es auch C direkt bedienen kann Zeiger.

Erfassung der Wortsegmentierungsergebnisse

Wie im obigen Code gezeigt, handelt es sich bei CJiebaWord für eine einzelne Wortsegmentierung nicht um die gespeicherte Wortsegmentierung, sondern um Satz + Offset, was bedeutet, dass das erste Wortsegmentierungsergebnis das Original sein muss Zeichenfolge. In der C-Demo handelt es sich um printf-Formatierung (. gibt Feldbreite und -ausrichtung an), aber es gibt keine ähnliche Methode in PHP. Sie müssen die Zeichenfolge substr($x->word, 0, $x->) abfangen ;len)

  for (x = words; x->word; x++) {
    printf("%*.*s\n", x->len, x->len, x->word);
  }

Verwendungsbeispiel

Dynamische Bibliothek kompilieren

make libjieba.so
Run

time php demo.php

C-Demo ausführen

make demo
time ./demo

Ergebnis

PHP
load: 0.00025701522827148
real    1m59.619s
user    1m56.093s
sys     0m3.517s
C
real    1m54.738s
user    1m50.382s
sys     0m4.323s
CPU 占用 基本都是 12%

Das finden Sie mit FFI, der Geschwindigkeit von PHP ist im Grunde dasselbe wie C. Bei hoher CPU-Auslastung Für Unternehmen können Sie versuchen, andere Sprachen (C/C++, Golang, Rust usw.) zu verwenden, um standardmäßige dynamische C-Bibliotheken zu schreiben und zu exportieren.

Verwendung von FFI

Bevor es FFI gab, wo Systemaufrufe oder SDK-Aufrufe erforderlich waren, war PHP für die Entwicklung von Erweiterungen erforderlich. Die Entwicklung von Erweiterungen erfordert jedoch nicht nur Kenntnisse der C-Sprache, sondern auch des PHP-Kernels, was mehr ist schwierig. Jetzt ist es viel bequemer, Sie können FFI direkt zum Aufrufen der dynamischen Bibliothek verwenden.

Erweiterte Makroerweiterung

Zum Beispiel gibt es in Hikvisions SDK gcc -E -P HCNetSDK.h -o HCNetSDK_unfold.h eine große Anzahl von Makros, die die Typdefinition unterstützen.

Originaladresse: https://github.com /dwdcth/phpjieba_ffi

Das obige ist der detaillierte Inhalt vonRufen Sie cjieba mit PHPs FFI auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:github.io. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen