Repository: jitsi/jiwer
Issue: This code is 100x faster:
Root cause: Architectural Constraint

```
import Levenshtein as Lev
def cer(self, s1, s2):
        """
        Computes the Character Error Rate, defined as the edit distance.

        Arguments:
            s1 (string): space-separated sentence
            s2 (string): space-separated sentence
        """
        s1, s2, = s1.replace(' ', ''), s2.replace(' ', '')
        return Lev.distance(s1, s2)

def wer(self, s1, s2):
        """
        Computes the Word Error Rate, defined as the edit distance between the
        two provided sentences after tokenizing to words.
        Arguments:
            s1 (string): space-separated sentence
            s2 (string): space-separated sentence
        """

        # build mapping of words to integers
        b = set(s1.split() + s2.split())
        word2char = dict(zip(b, range(len(b))))

        # map the words to a char array (Levenshtein packages only accepts
        # strings)
        w1 = [chr(word2char[w]) for w in s1.split()]
        w2 = [chr(word2char[w]) for w in s2.split()]

        return Lev.distance(''.join(w1), ''.join(w2))

For people confused about the import: `pip install python-Levenshtein`

The WER is defined as follows: 
![grafik](https://wikimedia.org/api/rest_v1/media/math/render/svg/7db6226f0c365982b94f221d68530bf8a6a50611)
See also here: [Word error rate WIkipedia](https://en.wikipedia.org/wiki/Word_error_rate)

Your code would have to be adapted like this:
`return Levenshtein.distance(''.join(w1), ''.join(w2))/float(len(w1))`

@DevZiegler I only showed the way to make the code faster.
Complete the code at your own.

Current benchmark:
```
executing wer with 1 sentences:
	mean=0.0003 sec std=0.0000 sec
executing wer with 10 sentences:
	mean=0.0134 sec std=0.0006 sec
executing wer with 50 sentences:
	mean=0.3261 sec std=0.0024 sec
executing wer with 100 sentences:
	mean=1.3144 sec std=0.0046 sec
```

Your code:
```
executing wer with 1 sentences:
	mean=0.0000 sec std=0.0000 sec
executing wer with 10 sentences:
	mean=0.0001 sec std=0.0000 sec
executing wer with 50 sentences:
	mean=0.0022 sec std=0.0001 sec
executing wer with 100 sentences:
	mean=0.0079 sec std=0.0002 sec
```

Although this solution is indeed much faster, it adds a C++ dependency. It would be nice if there was the possibility to use the old wer calculation without this dependency, maybe an option to choose wether to use C-level Levenshtein module or not.

Would you be able to share your scenario where the dependency of 
python-Levenstein is prohibitive?

On 26/05/2021 16:09, Gabriel Ziegler wrote:
>
> Although this solution is indeed much faster, it adds a C++ 
> dependency. It would be nice if there was the possibility to use the 
> old wer calculation without this dependency, maybe an option to choose 
> wether to use C-level Levenshtein module or not.
>
> —
> You are receiving this because you modified the open/close state.
> Reply to this email directly, view it on GitHub 
> <https://github.com/jitsi/jiwer/issues/7#issuecomment-848801198>, or 
> unsubscribe 
> <https://github.com/notifications/unsubscribe-auth/ABXEFA524KVNADNIXOOJMVDTPT6H5ANCNFSM4HAVTDVA>.
>


In an environment where C++ dependencies' installation are blocked because they are installed at system-level, but pip packages are enabled for instance. Does it make sense?

In such a case, the following error is raised because I don't have C++ dependencies.

```
Complete output (27 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win32-3.8
  creating build\lib.win32-3.8\Levenshtein
  copying Levenshtein\StringMatcher.py -> build\lib.win32-3.8\Levenshtein
  copying Levenshtein\__init__.py -> build\lib.win32-3.8\Levenshtein
  running egg_info
  writing python_Levenshtein.egg-info\PKG-INFO
  writing dependency_links to python_Levenshtein.egg-info\dependency_links.txt
  writing entry points to python_Levenshtein.egg-info\entry_points.txt
  writing namespace_packages to python_Levenshtein.egg-info\namespace_packages.txt
  writing requirements to python_Levenshtein.egg-info\requires.txt
  writing top-level names to python_Levenshtein.egg-info\top_level.txt
  reading manifest file 'python_Levenshtein.egg-info\SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  warning: no previously-included files matching '*pyc' found anywhere in distribution
  warning: no previously-included files matching '*so' found anywhere in distribution
  warning: no previously-included files matching '.project' found anywhere in distribution
  warning: no previously-included files matching '.pydevproject' found anywhere in distributi
on
  writing manifest file 'python_Levenshtein.egg-info\SOURCES.txt'
  copying Levenshtein\_levenshtein.c -> build\lib.win32-3.8\Levenshtein
  copying Levenshtein\_levenshtein.h -> build\lib.win32-3.8\Levenshtein
  running build_ext
  building 'Levenshtein._levenshtein' extension
  error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build T
ools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  ----------------------------------------
  ERROR: Failed building wheel for python-Levenshtein
```

My workaround was to checkout wer function to commit 2f1daee8b6 that is right before the Levenshtein implementation