scratch/content/html/fr/blog/2010-02-23-When-regexp-is-not-the-best-solution.md

113 lines
3.3 KiB
Markdown
Raw Normal View History

2010-04-15 09:20:27 +00:00
-----
# Custom
isHidden: false
menupriority: 1
kind: article
created_at: 2010-02-23T10:09:52+02:00
2010-04-26 14:04:44 +00:00
title: Quand se passer des expressions régulières ?
2010-04-15 09:20:27 +00:00
tags:
2010-04-26 14:04:44 +00:00
- programmation
2010-04-15 09:20:27 +00:00
- regexp
2010-04-26 14:04:44 +00:00
- expressions régulières
2010-04-15 09:20:27 +00:00
- extension
2010-04-26 14:04:44 +00:00
- fichier
2010-04-15 09:20:27 +00:00
-----
2010-04-26 14:04:44 +00:00
Les expressions régulières sont très utiles. Cependant, elles ne sont pas toujours la meilleure manière d'aborder certain problème autour des chaines de caractères.
Et surtout quand les transformations que vous voulez accomplir sont simples.
2010-04-15 09:20:27 +00:00
2010-04-26 14:04:44 +00:00
Je voulais savoir comment récupérer le plus vite possible l'extension d'un nom de fichier. Il y a trois manière naturelle d'accomplir celà :
2010-04-15 09:20:27 +00:00
<div><code class="ruby">
# regexp
str.match(/[^.]*$/);
ext=$&
# split
ext=str.split('.')[-1]
# File module
ext=File.extname(str)
</code></div>
2010-04-26 14:04:44 +00:00
A première vue, je pensais que l'expression régulière serait plus rapide que le `split` parce qu'il pouvait y avoir plusieurs de `.` dans un nom de fichier. Mais la majorité du temps il n'y a qu'un seul point par nom de fichier. C'est pourquoi j'ai réalisé que le `split` serait plus rapide. Mais pas le plus rapide possible. Il y a une fonction qui est dédiée à faire ce travail dans un module standard de ruby ; le module `File`.
2010-04-15 09:20:27 +00:00
2010-04-26 14:04:44 +00:00
Voici le code pour faire un benchmark :
2010-04-15 09:20:27 +00:00
<div><code class="ruby" file="regex_benchmark_ext.rb">
#!/usr/bin/env ruby
require 'benchmark'
n=80000
tab=[ '/accounts/user.json',
'/accounts/user.xml',
'/user/titi/blog/toto.json',
'/user/titi/blog/toto.xml' ]
puts "Get extname"
Benchmark.bm do |x|
x.report("regexp:") { n.times do
str=tab[rand(4)];
str.match(/[^.]*$/);
ext=$&;
end }
x.report(" split:") { n.times do
str=tab[rand(4)];
ext=str.split('.')[-1] ;
end }
x.report(" File:") { n.times do
str=tab[rand(4)];
ext=File.extname(str);
end }
end
</code></div>
2010-04-26 14:04:44 +00:00
Et voici les résultats :
2010-04-15 09:20:27 +00:00
<pre class="twilight">
Get extname
user system total real
regexp: 2.550000 0.020000 2.570000 ( 2.693407)
split: 1.080000 0.050000 1.130000 ( 1.190408)
File: 0.640000 0.030000 0.670000 ( 0.717748)
</pre>
2010-04-26 14:04:44 +00:00
En conclusion, les fonction dédiées sont meilleures que votre façon de faire (la plupart du temps).
2010-04-15 09:20:27 +00:00
2010-04-26 14:04:44 +00:00
## Chemin complet d'un fichier sans l'extension
2010-04-15 09:20:27 +00:00
<div><code class="ruby" file="regex_benchmark_strip.rb">
#!/usr/bin/env ruby
require 'benchmark'
n=80000
tab=[ '/accounts/user.json',
'/accounts/user.xml',
'/user/titi/blog/toto.json',
'/user/titi/blog/toto.xml' ]
puts "remove extension"
Benchmark.bm do |x|
x.report(" File:") { n.times do
str=tab[rand(4)];
path=File.expand_path(str,File.basename(str,File.extname(str)));
end }
x.report("chomp:") { n.times do
str=tab[rand(4)];
ext=File.extname(str);
path=str.chomp(ext);
end }
end
</code></div>
2010-04-26 14:04:44 +00:00
et voici les résultats :
2010-04-15 09:20:27 +00:00
<pre class="twilight">
remove extension
user system total real
File: 0.970000 0.060000 1.030000 ( 1.081398)
chomp: 0.820000 0.040000 0.860000 ( 0.947432)
</pre>
2010-04-26 14:04:44 +00:00
En conclusion du ce second benchmark. Un fonction simple est meilleure que trois fonctions dédiées. Pas de surprise, mais c'est toujours bien de savoir.