activerecord length - ¿Contar, tamaño, longitud...demasiadas opciones en Ruby?




vs size (6)

En la mayoría de los casos (por ejemplo, Array o String ) el size es un alias de length .

count normalmente viene de Enumerable y puede tomar un bloque de predicados opcional. Por lo tanto, enumerable.count {cond} es [roughly] (enumerable.select {cond}).length - por supuesto puede eludir la estructura intermedia ya que solo necesita el recuento de predicados coincidentes.

Nota: No estoy seguro si el count fuerza una evaluación de la enumeración si el bloque no está especificado o si cortocircuita la length si es posible.

Editar (¡y gracias a la respuesta de Mark!): count sin bloque (al menos para Arrays) no obliga a una evaluación. Supongo que sin un comportamiento formal está "abierto" para otras implementaciones, si forzar una evaluación sin un predicado alguna vez tiene sentido de todos modos.

Parece que no puedo encontrar una respuesta definitiva al respecto y quiero asegurarme de que entiendo esto al "n'º nivel" :-)

    a = { "a" => "Hello", "b" => "World" }
    a.count  # 2
    a.size   # 2
    a.length # 2

    a = [ 10, 20 ]
    a.count  # 2
    a.size   # 2
    a.length # 2

Entonces, ¿qué usar? Si quiero saber si a tiene más de un elemento, parece que no importa, pero quiero asegurarme de que entiendo la diferencia real. Esto se aplica a las matrices también. Obtuve los mismos resultados.

Además, me doy cuenta de que count / size / length tiene diferentes significados con ActiveRecord. En este momento estoy más interesado en el Ruby puro (1.92), pero si alguien quiere hablar sobre la diferencia que hace AR, también sería apreciado.

¡Gracias!


Tenemos varias formas de averiguar cuántos elementos en una matriz como .length , .size y .size . Sin embargo, es mejor usar array.size lugar de array.count . Porque. .size es mejor en rendimiento.


Encontré un buen answare en http://blog.hasmanythrough.com/2008/2/27/count-length-size

En ActiveRecord, hay varias maneras de averiguar cuántos registros hay en una asociación, y existen algunas diferencias sutiles en la forma en que funcionan.

post.comments.count: determina la cantidad de elementos con una consulta SQL COUNT. También puede especificar condiciones para contar solo un subconjunto de los elementos asociados (por ejemplo: conditions => {: author_name => "josh"}). Si configura un contador de caché en la asociación, #count devolverá ese valor almacenado en caché en lugar de ejecutar una nueva consulta.

post.comments.length: siempre carga los contenidos de la asociación en la memoria y luego devuelve la cantidad de elementos cargados. Tenga en cuenta que esto no obligará a una actualización si la asociación se ha cargado previamente y luego se crearon nuevos comentarios de otra manera (por ejemplo, Comment.create (...) en lugar de post.comments.create (...)).

post.comments.size - Esto funciona como una combinación de las dos opciones anteriores. Si la colección ya se ha cargado, devolverá su longitud igual que al invocar #length. Si aún no se ha cargado, es como llamar a #count.

También tengo una experiencia personal:

<%= h(params.size.to_s) %> # works_like_that !
<%= h(params.count.to_s) %> # does_not_work_like_that !

Para matrices y hashes, el size es un alias de length . Son sinónimos y hacen exactamente lo mismo.

count es más versátil: puede tomar un elemento o predicado y contar solo aquellos elementos que coinciden.

> [1,2,3].count{|x| x > 2 }
=> 1

En el caso de que no proporcione un parámetro para contar, tiene básicamente el mismo efecto que la longitud de la llamada. Sin embargo, puede haber una diferencia de rendimiento.

Podemos ver en el código fuente de Array que hacen casi exactamente lo mismo. Aquí está el código C para la implementación de array.length :

static VALUE
rb_ary_length(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    return LONG2NUM(len);
}

Y aquí está la parte relevante de la implementación de array.count :

static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
    long n = 0;

    if (argc == 0) {
        VALUE *p, *pend;

        if (!rb_block_given_p())
            return LONG2NUM(RARRAY_LEN(ary));

        // etc..
    }
}

El código de array.count realiza algunas comprobaciones adicionales, pero al final llama al mismo código: LONG2NUM(RARRAY_LEN(ary)) .

Por otro lado, los hashes ( código fuente ) no parecen implementar su propia versión optimizada de count por lo que se usa la implementación de Enumerable ( código fuente ), que itera sobre todos los elementos y los cuenta uno a uno.

En general, recomendaría usar la length (o su size alias) en lugar de count si quieres saber cuántos elementos hay en total.

En cuanto a ActiveRecord, por otro lado, hay diferencias importantes. echa un vistazo a esta publicación:


Existe una diferencia crucial para las aplicaciones que hacen uso de las conexiones de bases de datos.

Cuando está utilizando muchos ORM (ActiveRecord, DataMapper, etc.), el entendimiento general es que .size generará una consulta que solicita todos los elementos de la base de datos ('select * from mytable') y luego le dará el número de elementos resultante, mientras que .count generará una sola consulta ('select count (*) from mytable') que es considerablemente más rápido.

Debido a que estos ORM son tan frecuentes, sigo el principio de menos asombro. En general, si ya tengo algo en la memoria, uso .size, y si mi código generará una solicitud a una base de datos (o servicio externo a través de una API), uso .count.






ruby activerecord size content-length