Regex & Lambda
Prima della cura:
private static string FormatLinks(string input, bool insideLink)
{
MatchCollection matches = inlineUrls.Matches(input);
if (matches.Count == 0)
{
return input;
}
StringBuilder sb = new StringBuilder(input.Length * 2);
int inputIndex = 0;
foreach (Match tag in matches)
{
// add the normal text between the
// current index and the index of the current tag
if (inputIndex < tag.Index)
{
sb.Append(input.Substring(inputIndex, tag.Index - inputIndex));
}
string url = tag.Value;
sb.AppendFormat(insideLink ? "{1}" :
"<a target='blank' href='{0}'>{1}</a>", url,
HtmlHelper.ReduceUrlLength(url, maxUrlLength));
inputIndex = tag.Index + tag.Length;
}
// add remainder
if (inputIndex < input.Length)
{
sb.Append(input.Substring(inputIndex));
}
return sb.ToString();
}
Dopo la cura
private static string FormatLinks(string input, bool insideLink)
{
return inlineUrls.Replace(input, m =>
{
return String.Format(insideLink ?
"{1}" : "<a target='blank' href='{0}'>{1}</a>",
m.Value,
HtmlHelper.ReduceUrlLength(m.Value, maxUrlLength));
}
);
}
Interessante anche il fatto che, sebbene normalmente le lambda siano meno leggibili, nel caso specifico la riduzione di codice ridondante rende l’intenzione più evidente.
-quack
P.S. è un periodo in cui sniffo RegEx da mattina a sera; dienticavo: grazie all’enorme lavoro di refactoring i link nella nuvoletta sono ora cliccabili, per la gioia di Dovella
Potrebbero interessarti anche:
- Tor exit node lookup in ASP.Net
- Metodi dinamici di delegazione
- Lunedì quiz 4–soluzione
- Windows Live Writer plugin: footnote
- Lunedì quiz - risposte


Facebook,
Wikio,
Segnalo.

venerdì 3 luglio 2009 alle 7:42 PM -
Me ne sono accorto subito stamattina
PS. hai visto il post in OT con WM e Opera?
PS PS- dai che oggi dovrebbe essere il grande giorno (spero)
sennò piglioo a capate il Postale
Permalink - Rispondi al commento
venerdì 3 luglio 2009 alle 7:47 PM -
Lo spero anche io visto che sono a casa e le raccomandate vanno firmate
Permalink - Rispondi al commento
venerdì 3 luglio 2009 alle 9:20 PM -
Avessi capito una riga di codice sarei felice!
Permalink - Rispondi al commento
venerdì 3 luglio 2009 alle 9:56 PM -
@ Phenix
Converte l'indirizzo di un sito (es tiziocaio&sempronio.com) ed il nome associato (Il triumvirato) nel codice html corrispondente (< a traget='blank' href='tiziocaio&sempronio.com' >Il triumvirato< /a >, senza spazi prima e dopo i bracket).
Faccio notare che gia' la prima implementazione e' molto piu' elegante di quella che scriverei io, la seconda non ha confronto
Unico dubbio: se scrivo
devo chiamare i pompieri?
Edward
Permalink - Rispondi al commento
venerdì 3 luglio 2009 alle 10:57 PM -
Grazie Edward, sarà che di C# sono completamente a digiuno, mai scritta una riga di codice! Solo qualche modestissima cosa in Java per l'università...
Permalink - Rispondi al commento
venerdì 3 luglio 2009 alle 11:49 PM -
@ Phenix:
Io non conosco il C# e mastico pochissimo Java (una mentina o poco piu'
): a intuito dovrebbe convertire gli indirizzi, ma posso sempre sbagliarmi.
Edward
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 12:27 AM -
Non esiste limite al refactoring o all'ottimizzazione spinta?
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 1:09 AM -
La demenza senile o un ictus
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 10:23 AM -
@0verture:
LOL, a momenti sputavo il caffè per il tuo commento!
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 11:06 AM -
Ahahahhahahahahhahahahaha
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 3:40 PM -
Paperino, esempio molto istruttivo, sarebbe bello capire se questo tipo di refactoring ha impatto sulle performance.
Nella versione "prima della cura" fai prima un match per estrarre dalla lista solo gli Urls che corrispondono all'input e poi per ognuno di questi match applichi la trasformazione del caso.
Nella versione "dopo la cura" viene fatto un replace per ogni Urls, ma non ho idea se lo string.Format venga eseguito solo per le Urls che matchano l'input o venga fatto per tutti gli Urls (chiaramente dove non c'e' match il replace non fa alcun replace).
Non e' che nella versione "cool" si fanno cose "evitabili" e quindi con un impatto sulle performance? Magari nell'esempio specifico l'impatto non e' significativo ma in generale c'e' questo problema con questo tipo di refactoring?
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 5:05 PM -
@nonno:
La semantica di RegEx.Replace è quella di invocare la funzione delegate solo per le stringhe da rimpiazzare, quindi i due pezzi di codice sono praticamente identici. L'unico overhead nel secondo caso è il costo di invocazione del metodo che non è gratuito. Sarebbe interessante misurare, lo farò con calma.
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 5:41 PM -
5000 iterazioni, diverse esecuzioni con risultati in linea.
Iterativo Millisecs: 15608
Lambda Millisecs: 16419
5% circa. Secondo me vale assolutamente la pena. O no?
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 5:46 PM -
Vale!
Dovro' studiarmele bene 'ste espressioni lambda, sono decisamente interessanti
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 8:18 PM -
C'è un problema con la visualizzazione dell'immagine: aovestdipaperino.com/blog/smileys/confused.gif nel riquadro dei pensieri di Paperino.
Mi sa che ti tocca giocare ancora un po' con le RegExp
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 9:03 PM -
Good catch wisher, oggi mi 'riposo' però
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 9:06 PM -
A prima vista si direbbe che il secondo codice è più ottimizzato del primo però guardato dal punto di vista di qualcuno che dovrebbe implementare un simile codice in un sistema embedded quindi dotato di poca memoria, se si dovessero riscrivere entrambi i codici senza far uso di librerie e funzioni già pronte, quale sarebbe il più compatto ?
Permalink - Rispondi al commento
sabato 4 luglio 2009 alle 9:55 PM -
@wisher:
ho errato nell'ordine di applicazione dei filtri (prima vanno convertite le URL e poi gli smiley), però il risultato non avrebbe dovuto essere così disastroso.
Il baco è sistemato ma dentro di esso c'è nascosto un baco più piccolo che aspetta di venire fuori. Se non ci dormo lo scovo...
Permalink - Rispondi al commento