Penso che la domanda è il motivo per cui sono in esecuzione questo script di frequente? Stai eseguendo i calcoli (le stringhe sostituite) sugli stessi dati più e più volte, o lo stai facendo su dati diversi ogni volta?
Se la risposta è la prima, non c'è molto altro da fare per migliorare le prestazioni sul lato PHP. È possibile migliorare le prestazioni in altri modi, ad esempio utilizzando hardware migliore (SSD per letture/scritture più veloci sui file), CPU multicore e suddividendo i dati in parti più piccole eseguendo più script contemporaneamente per elaborare i dati contemporaneamente e RAM più veloce (ovvero velocità bus più elevate).
Se la risposta è la seconda, allora si potrebbe prendere in considerazione la memorizzazione nella cache il risultato utilizzando qualcosa di simile (negozi di cache chiave/valore) memcached o REDDIS modo che si può eseguire solo il calcolo una volta e poi è solo una lineare letto dalla memoria , che è molto economico e non richiede praticamente alcun sovraccarico della CPU (, potresti anche utilizzare la cache della CPU a questo livello).
La manipolazione delle stringhe in PHP è già a buon mercato perché le stringhe di PHP sono essenzialmente solo array di byte. Non c'è praticamente nessun sovraccarico da parte di PHP nel leggere un file in memoria e archiviarlo in una stringa.Se hai qualche codice di esempio che dimostra dove stai vedendo problemi di prestazioni e alcuni numeri di benchmark, potrei avere un consiglio migliore, ma al momento sembra che tu abbia bisogno di rifattorizzare il tuo approccio in base a quali sono le tue esigenze di fondo.
Ad esempio, i costi di CPU e I/O vengono considerati singolarmente quando si utilizzano dati in situazioni diverse. I/O implica il blocco poiché si tratta di una chiamata di sistema. Ciò significa che la tua CPU deve attendere che altri dati arrivino sul filo (mentre il tuo disco trasferisce i dati in memoria) prima che possa continuare a elaborare o calcolare quei dati. La tua CPU sarà sempre molto più veloce della memoria e la memoria è sempre molto più veloce del disco.
Ecco un punto di riferimento semplice per mostrare la differenza:
/* First, let's create a simple test file to benchmark */
file_put_contents('in.txt', str_repeat(implode(" ",range('a','z')),10000));
/* Now let's write two different tests that replace all vowels with asterisks */
// The first test reads the entire file into memory and performs the computation all at once
function test1($filename, $newfile) {
$start = microtime(true);
$data = file_get_contents($filename);
$changes = str_replace(array('a','e','i','o','u'),array('*'),$data);
file_put_contents($newfile,$changes);
return sprintf("%.6f", microtime(true) - $start);
}
// The second test reads only 8KB chunks at a time and performs the computation on each chunk
function test2($filename, $newfile) {
$start = microtime(true);
$fp = fopen($filename,"r");
$changes = '';
while(!feof($fp)) {
$changes .= str_replace(array('a','e','i','o','u'),array('*'),fread($fp, 8192));
}
file_put_contents($newfile, $changes);
return sprintf("%.6f", microtime(true) - $start);
}
Le due prove precedenti fanno la stessa cosa esatta, ma Test2 si rivela significativamente più veloce per me quando sto usando piccole quantità di dati (circa 500 KB in questo test).
Ecco il punto di riferimento è possibile eseguire ...
// Conduct 100 iterations of each test and average the results
for ($i = 0; $i < 100; $i++) {
$test1[] = test1('in.txt','out.txt');
$test2[] = test2('in.txt','out.txt');
}
echo "Test1 average: ", sprintf("%.6f",array_sum($test1)/count($test1)), "\n",
"Test2 average: ", sprintf("%.6f\n",array_sum($test2)/count($test2));
Per me il punto di riferimento di cui sopra dà Test1 average: 0.440795
e Test2 average: 0.052054
, che è un ordine di grandezza differenza e questo è solo la prova su 500KB di dati. Ora, se aumento la dimensione di questo file a circa 50MB Test1 in realtà si dimostra più veloce poiché ci sono meno chiamate I/O di sistema per iterazione (ovvero stiamo leggendo dalla memoria linearmente in Test1), ma più Costo della CPU (ovvero stiamo eseguendo un calcolo molto più grande per iterazione). Generalmente la CPU si dimostra in grado di gestire quantità di dati molto più elevate alla volta rispetto a quanto i dispositivi I/O possono inviare sul bus.
Quindi nella maggior parte dei casi non è una soluzione valida per tutti.
questo è grande domanda. +1 da me. Vedo che stai usando i file. Puoi passare al database in qualche modo? se no, possiamo vedere alcuni dati dai file? – pregmatch
Come vengono lette e gestite le stringhe? Hai confrontato la sostituzione della stringa con l'effettiva apertura di file o flussi? Piattaforma? – Daniel
Non c'è niente di speciale nei file, è solo una questione di sostituzione dei caratteri di sottolineatura, rimozione di virgole, sostituzione di caratteri non UTF8, ecc. –